473,385 Members | 1,693 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

LINQ Dynamic Data Model

My problem is this. Our clients create different fields they want to
collect and we allow them build dynamic filters, reports etc...
We run some TSQL to actually create the column and all works very well. We
are now adding a lot more functionality to our filters and could really
benefit from using the LINQ to SQL.

I have experimented with the Dynamic Linq
(http://weblogs.asp.net/scottgu/archi...y-library.aspx)
and it is exactly what we need to let them create their own filters and
such. But when I try to filter on a column that does not exist in the Data
Context I get an error, which is understandable.

They have one table that they can add columns to, so I am going to attempt
to dynamically add the new properties and attributes before running the LINQ
query.

For example, if a client adds a new column called Age of type Int, I want to
add a new property to the object.
So it looks like I need to add a property that looks something like:

[Column(Storage="Age", DbType="Int NOT NULL")]
public int Age { get; set;}

I've been reading different reflection techniques and examples for the past
two days and seems like I'm going around in circles..
Does anyone have any suggestions on how I might accomplish this? Anything
to point me in the right direction would be greatly appreciated.
Jan 15 '08 #1
15 10818
I have opposite experience.

I was meaning coding against a known data-context in the c#, not a
base-class - is this still the case? Or are you generating the context
at runtime too? (in which case, coding gets very hard)

But your thoughts are definitely useful here - I suspect you've spent
more time trying to get this scenario working than the rest of us
combined ;-p

Marc
Jan 15 '08 #2
EDBrian wrote:
Should I use the Reflection.Emit to create the derived
type/properties? Like I said in my original post, I've been looking
into reflection and creating a new class dynamically for a couple
days now. Do you have any suggestions or links that might help....
And how are you going to refer to these new properties in your code,
which only appear at runtime?

Dynamic columns at runtime should be solved differently: with a couple
of related tables, one for the values and one for the fields. It is a
bit hard on the querying side, but it's what's possible as the language
used in the program is a statically typed language.

FB
--
------------------------------------------------------------------------
Lead developer of LLBLGen Pro, the productive O/R mapper for .NET
LLBLGen Pro website: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------
Jan 16 '08 #3
Should I use the Reflection.Emit to create the derived type/properties?
Like I said in my original post, I've been looking into reflection and
creating a new class dynamically for a couple days now.
Do you have any suggestions or links that might help....
As I wrote there are simpler things than Reflection.Emit:

1. Dynamic Compilation to create assembly. I think I have posted some sample
earlier for Marc in this newsgroup.

2. I just discovered from you link Dynamic Linq library CreateClass()
method, thanks a lot.
Maybe this can be used, if it allows to specify base class and Attributes to
properties, any experiences ?

Sample in doc is very promising:

DynamicProperty[] props = new DynamicProperty[] {
new DynamicProperty("Name", typeof(string)),
new DynamicProperty("Birthday", typeof(DateTime)) };
Type type = DynamicExpression.CreateClass(props);
object obj = Activator.CreateInstance(type);
t.GetProperty("Name").SetValue(obj, "Albert", null);
t.GetProperty("Birthday").SetValue(obj, new DateTime(1879, 3, 14), null);
Console.WriteLine(obj);
I think we must create some class which allows this easily.

Andrus.
Jan 16 '08 #4
Nothing yet. I can't figure out how to specify a base class...then I'm
thinking of using reflection to copy all the properties in my static class
to the new one.
"Andrus" <ko********@hot.eewrote in message
news:ev**************@TK2MSFTNGP05.phx.gbl...
>Should I use the Reflection.Emit to create the derived type/properties?
Like I said in my original post, I've been looking into reflection and
creating a new class dynamically for a couple days now.
Do you have any suggestions or links that might help....

As I wrote there are simpler things than Reflection.Emit:

1. Dynamic Compilation to create assembly. I think I have posted some
sample earlier for Marc in this newsgroup.

2. I just discovered from you link Dynamic Linq library CreateClass()
method, thanks a lot.
Maybe this can be used, if it allows to specify base class and Attributes
to properties, any experiences ?

Sample in doc is very promising:

DynamicProperty[] props = new DynamicProperty[] {
new DynamicProperty("Name", typeof(string)),
new DynamicProperty("Birthday", typeof(DateTime)) };
Type type = DynamicExpression.CreateClass(props);
object obj = Activator.CreateInstance(type);
t.GetProperty("Name").SetValue(obj, "Albert", null);
t.GetProperty("Birthday").SetValue(obj, new DateTime(1879, 3, 14), null);
Console.WriteLine(obj);
I think we must create some class which allows this easily.

Andrus.
Jan 16 '08 #5
EDBrian,

Why not to use use dynamic compilation ?

In design time create wrapper assembly used to satisfy MSBUILD.

At runtime:

1. In start of Main() delete this wrapper assembly

2. In AssemblyResolve event:
2.1 create source code cs file in code for child class, specify base class
from other assembly.
2.2 compile it to assembly
2.3 return this assembly reference in in assemblyresolve event thus
replacing original assembly.

Andrus.

"EDBrian" <pr*****@newsgroups.nospamwrote in message
news:4A**********************************@microsof t.com...
Nothing yet. I can't figure out how to specify a base class...then I'm
thinking of using reflection to copy all the properties in my static class
to the new one.

Jan 16 '08 #6
Is this a good idea even in a web appliation?
We don't have that much traffic, I'm not worried about the possible
execution time, but if I destroy the "currnet type" then create a new type
would it effect other clients if they happen to be accessing the object?

As an experiment I created another partial class (with the same name) and
simply added:

[Column(DbType = "Int")]
public int Age { get; set; }

And I can successfully query my database using the "Age" field. I am trying
to figure out how to add a property to a class dynamically. I am out of
element so it's taking a very long time.
I did find this post:
http://blog.devstone.com/aaron/archi...0/24/1323.aspx
But I think it confused me even more. Can I use the
TypeBuilder/PropertyBuilder on an already existing type or should I go back
to the drawing board?

I even stepped through the System.Linq.Dynamic.ExpressionParser and found
this on line 1336:
MemberInfo[] members = t.FindMembers(MemberTypes.Property |
MemberTypes.Field, flags, Type.FilterNameIgnoreCase, memberName);

So now I'm thinking that maybe I can add another method to accomplish
this...something like:

if(members.length == 0){
//Look for a specific property or method that I can add "Custom Fields"
to..
}

But that is a reach....
"Andrus" <ko********@hot.eewrote in message
news:%2****************@TK2MSFTNGP03.phx.gbl...
EDBrian,

Why not to use use dynamic compilation ?

In design time create wrapper assembly used to satisfy MSBUILD.

At runtime:

1. In start of Main() delete this wrapper assembly

2. In AssemblyResolve event:
2.1 create source code cs file in code for child class, specify base class
from other assembly.
2.2 compile it to assembly
2.3 return this assembly reference in in assemblyresolve event thus
replacing original assembly.

Andrus.

"EDBrian" <pr*****@newsgroups.nospamwrote in message
news:4A**********************************@microsof t.com...
>Nothing yet. I can't figure out how to specify a base class...then I'm
thinking of using reflection to copy all the properties in my static
class to the new one.

Jan 16 '08 #7
Is this a good idea even in a web appliation?

Yes, this is a good idea.
We don't have that much traffic, I'm not worried about the possible
execution time, but if I destroy the "currnet type" then create a new type
would it effect other clients if they happen to be accessing the object?
You base type and base properties reside is assembly which is not destoryed.
You create wrapper assembly contianing initially no properties.
You delete this wrapper assembly and replace it with new wrapper assembly
containing additional properties defined by web user at run time.
As an experiment I created another partial class (with the same name) and
simply added:

[Column(DbType = "Int")]
public int Age { get; set; }
..NET does not support partial assemblies.
Partial classes require the full source code of whole class to build
assembly.
It is not reasonable to distribute source code with application.
So using partial classes is not possible.
And I can successfully query my database using the "Age" field. I am
trying to figure out how to add a property to a class dynamically. I am
out of element so it's taking a very long time.
I did find this post:
http://blog.devstone.com/aaron/archi...0/24/1323.aspx
But I think it confused me even more. Can I use the
TypeBuilder/PropertyBuilder on an already existing type or should I go
back to the drawing board?
As Marc wrote, Linq does not support properties created using
TypeDescriptor.
So this is not possible.
You can try dynamic compiling example I posted is this newsgroup some time
ago.
If you encounter issues with this I can help you since I use this example
based approach.
I even stepped through the System.Linq.Dynamic.ExpressionParser and found
this on line 1336:
MemberInfo[] members = t.FindMembers(MemberTypes.Property |
MemberTypes.Field, flags, Type.FilterNameIgnoreCase, memberName);

So now I'm thinking that maybe I can add another method to accomplish
this...something like:

if(members.length == 0){
//Look for a specific property or method that I can add "Custom Fields"
to..
}
You can add property by implementing custom TypeDescriptor.
Unfortunately Linq current implementation is not capable to use properties
defined through TypeDesciptor interfase.
Linq current implementation it uses Reflection GetProperties() directly.

Your property would be used only for consumers which use TypeDescriptor
interface like DataGridView or data binding.

Only way is to use dynamic compiling or Reflection.Emit to create new type
in new assembly.

Andrus.
Jan 17 '08 #8
I'm sold...with your suggestion of:
You base type and base properties reside is assembly which is not
destoryed.
You create wrapper assembly contianing initially no properties.
You delete this wrapper assembly and replace it with new wrapper assembly
containing additional properties defined by web user at run time.
I can't find your post from the past...do you happen to have a link to it?
I'm stepping out of my comfort zone here and would love to see an
example/explination to point me in the right direction.

Any pointers or good reads you can help me with?

Jan 17 '08 #9
>You base type and base properties reside is assembly which is not
>destoryed.
You create wrapper assembly contianing initially no properties.
You delete this wrapper assembly and replace it with new wrapper assembly
containing additional properties defined by web user at run time.

I can't find your post from the past...do you happen to have a link to it?
I'm stepping out of my comfort zone here and would love to see an
example/explination to point me in the right direction.

Any pointers or good reads you can help me with?
I can send vs2008 solution to you by e-mail.

Andrus.

Jan 17 '08 #10
I'd appreciate it...

how about...prizeloop at yahoo . com

"Andrus" <ko********@hot.eewrote in message
news:uz****************@TK2MSFTNGP03.phx.gbl...
>>You base type and base properties reside is assembly which is not
destoryed.
You create wrapper assembly contianing initially no properties.
You delete this wrapper assembly and replace it with new wrapper
assembly
containing additional properties defined by web user at run time.

I can't find your post from the past...do you happen to have a link to
it?
I'm stepping out of my comfort zone here and would love to see an
example/explination to point me in the right direction.

Any pointers or good reads you can help me with?

I can send vs2008 solution to you by e-mail.

Andrus.
Jan 17 '08 #11
I'd appreciate it...

I sent it.

Andrus.
Jan 18 '08 #12
Thanks...I haven't received it yet....but I'll keep an eye out.
(prizeloopATyahoo.c0m)

It looks like you are the reflection expert so I've these might be dumb
questions, but here we go.
I can easily create a dynamic class right:
-----------------------------------------
DynamicProperty[] props = new DynamicProperty[]{
new DynamicProperty("Age", typeof(int)),
new DynamicProperty("Birthday", typeof(DateTime))
};
Type typ = DynamicExpression.CreateClass(props);
object obj = Activator.CreateInstance(typ);
-----------------------------------------

And again (just to reiterate) I don't need any compile time checking...I
just want the Dynamic LINQ not to throw an exception.
Is there some way I can do something of this sort (I know this doesn't work,
just trying to get my point across):
-----------------------------------------
Table<ADummyClasstable =
datacontext.GetTable(typeof(Facade.CreateDynamicTy pe)) as
Table<ADummyClass>;
-----------------------------------------

As I'm sure you know the problem is the typeof(Facade.CreateDynamicType)
because "CreateDynamicType" is a property and not a class.
I've tried some quick tests by making the CreateDynamicType a method that
returns a Type and other stupid ideas that just didn't work.

What do you think? Is this something I should pursue, getting the
"typeof(Facade.ReturnDyanmicSomething)"? Or should I work on trying to
re-create the "ADummyClass" at runtime? Again, creating a class wasn't that
hard using the DynamicExpression.Createclass() method, but I am out of my
element trying to delete the "ADummyClass" and creating a new one at
runtime...

Thoughts?

Jan 18 '08 #13
Thanks...I haven't received it yet....but I'll keep an eye out.
(prizeloopATyahoo.c0m)
I sent it a lot of hours ago so you should received it.
I uploaded it to

http://eetasoft.ee/eevalinq.zip
It looks like you are the reflection expert
I'm just learning C# and Linq. I'm not expert in any way.
Is there some way I can do something of this sort (I know this doesn't
work, just trying to get my point across):
-----------------------------------------
Table<ADummyClasstable =
datacontext.GetTable(typeof(Facade.CreateDynamicTy pe)) as
Table<ADummyClass>;
-----------------------------------------
I use DbLinq Generic GetTable<ADummyClassfunction for similar case like

class MyForm<ADummyClass {
....
Table<ADummyClass tbl = datacontext.GetTable<ADummyClass>();
....
}

I think it is possible to create your function GetTable( Type t )
which uses reflection to pass type t to GetTable<ADummyClass>() function.

Thoughts?
MakeGenericType() is nice function.

Andrus.
Jan 18 '08 #14
Typically you create two tables: one for the field definitions and one for the values
for these fields per row.
See also: http://groups.google.com/group/micro...3d69c83f1401c3

Same idea, but keeping the values in one place rather than a separate
table; you still need the field definitions, though.

Marc
Jan 19 '08 #15
So currently I'm thinking that it is not worth to change database structure
and application concepts in my case.
I agree; my xml answer was mainly aimed at what sounds like a green-
field implementation.
However this requires creating new
linq driver which translates custom property operations to xml operations in
this column.
Well, that's the kicker. First - I actually really like the LINQ idea,
but the one thing that *really, really, really* annoys me about the
LINQ /implementation/ is that Expression is bound to a MemberInfo, not
something more abstract. That makes it simply impossible to create an
Expression based on a dynamic PropertyDescriptor; and without an
Expression there is nothing for a provider to work with - regardless
of what that provider is. So without re-writing Expression we will
*never* be able to create a sort etc on such a property.

This is truly disappointing; I know /why/ they did it (since
Reflection.Emit uses MemberInfo etc) - but it would have been just as
easy to allow an *abstract* implementation, and *if* they detect that
it is a reflection implementation then locate the matching MemberInfo,
otherwise just invoke the descriptor. Oh well.

For info, not LINQ - but I have written an ORM-esque "search"
implementation that *can* query / sort etc within an xml column
(provided that the somewhere describes the xpath for the property in
question), but it ain't gonna work with LINQ ever as far as I can
tell.

But : if the use case is to store some additional data against a
record, it will do the job quite nicely, without the complexity of
joining through 2 other tables to get the data.

It all depends on what you want to achieve.

Marc

But
Jan 19 '08 #16

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Marshal | last post by:
I've just had a chance to review LINQ, DLinq, and XLinq, (which I only heard about last week after the PDC). The various LINQs actually seem to live up to expectations - Using query semantics to...
7
by: Chris | last post by:
I am a little confused. I have been reading about LINQ and it seems to imply LINQ is available in C# 3 but not in Visual Studio until the next release. I am a VB.net programmer but would still like...
7
by: Ronald S. Cook | last post by:
I've always been taught that stored procedures are better than writing SQL in client code for a number of reasons: - runs faster as is compiled and lives on the database server - is the more...
28
by: Marc Gravell | last post by:
In Linq, you can apparently get a meaningful body from and expression's .ToString(); random question - does anybody know if linq also includes a parser? It just seemed it might be a handy way to...
1
by: Lacutas | last post by:
Hi I'm having some problems getting a dynamic LINQ query to work on my DataSet. The idea is that a user selects certain criteria, and then the LINQ query filters through the dataset making the...
1
by: Frederik | last post by:
Hi all, Am I correct when stating that LINQ replaces somewhat DataTables? I have done some reading concerning LINQ, but I'm still puzzled as to whether I should use LINQ or not. My application...
2
by: Mucahit ikiz | last post by:
I cant make a full dynamic query in LINQ I have 2 situation methods (only_exp_query, only_tbl_query) those are working. .... using System.Linq.Dynamic; using System.Data.Linq; .... string...
6
by: Plissskin | last post by:
I need to create an "ad-hoc" filtering page in a web app we are building. The page would display a number of drop down lists, text boxes, and radio lists and allow the user to select (enter) some...
2
by: giddy | last post by:
hi, Yes its a design question again. =) If I have something like: class Person { //functions: static Person GetAllPersons(); static Person Search(string field,string value);
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.