LINQ Dynamic Data Model

F

Frans Bouma [C# MVP]

Andrus said:
Frans,


MS Dynamic Linq Library usage contains of samples about this. First
sample in its doc looks like:

var query =
db.Customers.
Where("City = @0 and Orders.Count >= @1", "London", 10).
OrderBy("CompanyName").
Select("new(CompanyName as Name, Phone)");

You can replace string constans with variables determined at runtime.

ah, back to string-based programming... why do we need Linq with
compile time checked stuff when we have string based queries! ;)
No. Never.
This is too hard to code.

No it's quite easy, give it a try :)

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#)
------------------------------------------------------------------------
 
A

Andrus

why do we need Linq with compile time checked stuff when we have string
based queries! ;)

90% of cases whole compile times check is OK.

For remaining 6% cases dynamic properties can be used. This allows compile
time check part of select clause.
For example when you use dynamic orderby

var query =
( from c in db.Customers.
where City=myCity
select Phone ).
OrderBy("CompanyName");

Compiler checks all clauses except order by.

For remaining 4% of cases string based queries should be used in current
linq implementation level.
No it's quite easy, give it a try :)

Can you provide example how to add Age property to Northwind Customers table
at run time ?

Andrus.
 
E

EDBrian

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<ADummyClass> table =
datacontext.GetTable(typeof(Facade.CreateDynamicType)) 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?
 
A

Andrus

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<ADummyClass> table =
datacontext.GetTable(typeof(Facade.CreateDynamicType)) as
Table<ADummyClass>;
-----------------------------------------

I use DbLinq Generic GetTable<ADummyClass> function 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 )
Thoughts?

MakeGenericType() is nice function.

Andrus.
 
F

Frans Bouma [C# MVP]

Andrus said:
90% of cases whole compile times check is OK.

For remaining 6% cases dynamic properties can be used. This allows
compile time check part of select clause. For example when you use
dynamic orderby

var query =
( from c in db.Customers.
where City=myCity
select Phone ).
OrderBy("CompanyName");

Compiler checks all clauses except order by.

For remaining 4% of cases string based queries should be used in
current linq implementation level.

no, you don't have to. You can concat queries without falling back to
strings. String based queries are going to hurt you sooner or later, as
they break at runtime.
Can you provide example how to add Age property to Northwind
Customers table at run time ?

I've already explained this to you in an earlier post. Typically you
create two tables: one for the field definitions and one for the values
for these fields per row.

It's a bit arcane as you're re-doing the RDBMS model in a table, but
it is usable in statically typed languages, as the extra fields are
actually related entities so it can be used at runtime without prior
notice what the fields are.

However adding fields at runtime the other way (altering the actual
table) is going to be more work IMHO, as your program can never be
tested properly nor proven to be working OK, as the actual code is
never available to you.

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#)
------------------------------------------------------------------------
 
A

Andrus

Typically you create two tables: one for the field definitions and one
See also:
http://groups.google.com/group/micr....csharp/browse_thread/thread/343d69c83f1401c3

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

Marc,

Adding single xml column is interesting. However this requires creating new
linq driver which translates custom property operations to xml operations in
this column. AFAIK no such driver exists.

I have existing database schema deployed to a large number of customer
sites. This schema has table DataDict

Create table DataDict ( FIELD_NAME Char(10),
FIELD_TYPE Char(1),
FIELD_LEN Numeric(3),
FIELD_DEC Numeric(3),
TABLE_NAME Char(8) );

Current non-.net client adds new columns or even modifies extisitng char
field widths to existing database tables when user adds new row to this
table.
In 15% of customer sites (but they are large customers most important)
there are a number of fields added to up to 10 tables using this approach.

I'm looking a way to create c# client application which can use existing
data from this database.
Using your appoach requires re-factoring existing database structure and
creating new algorithms.
Without that I only need to re.-write existing aspplication in new language
using algorithms probed in old application.

This is a huge additional work.

I do'nt now will the result be better (more code maintainablility) or not.
Adding new real properties to entites in the fly seems to be less work.

So currently I'm thinking that it is not worth to change database structure
and application concepts in my case.

Andrus.
 
M

Marc Gravell

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top