views:

54

answers:

2

I have a simlar requirement where in i have 3 main entities in ADO.NET entity model... I am building a framework wherein basedon incoming XML root element i have to create an instance of specific entity using reflection and set its properties..

But when it comes to child entities.. I am not able to use LINQ queries on it as the type is not known at design time. PropertyInfo.GetValue gives me an object on which i can not run LINQ queries (even when i typecast it to IQueryable or IEnumerable). I am not even able to typecast it at design time as that would be kind of hardcoding and will fail my generic framework purpose.

I tried to use dynamic keyword.. but on that too i can not write LINQ queries.. it gives a message that LINQ queries are not supported on dynamic dispatch model.!!!

Can someone help..

Regards Badal

A: 

Like @Yuriy Faktorovich recommended, dynamic LINQ may be your best shot.

Another option you have is to dynamically build expression trees and execute your expression via reflection. Keep in mind that this is not easy and may take a little time to wrap your head around the expression API, but for simple expression it's not too bad.

Example: Say you want to replicate this expression:

p => p.FirstName == firstName

You can build the expression tree as follows:

var myType = Type.GetType("Person"); // <-- Find your type based on XML
var firstName = "John";

var param = Expression.Parameter(myType, "p");
var firstNameProperty = Expression.Property(param, "FirstName");
var constantExpression = Expression.Constant(firstName);
var equalsExpression = Expression.Equal(firstNameProperty, constantExpression);

var lambda = Expression.Lambda(equalsExpression, param);

The lambda will have a runtime type of Expression<Func<Person,bool>> which you can then pass to any IQueryable implementation.

UPDATE

Then to dynamcially call some method on your IQueryable you can do something similar to the following:

var queryableType = typeof(Queryable);
var whereMethod = queryableType.GetMethod("Where", BindingFlags.Public | BindingFlags.Static);

var parameters = new object[] { query, lambda }; // query is your IQueryable object
var list = whereMethod.Invoke(null, parameters);
Wallace Breza
Thanks for your response.. Looks like this can solve my problem.. but I did not understand this part of your commentThe lambda will have a runtime type of Expression<Func<Person,bool>> which you can then pass to any IQueryable implementationMy next question is .. how do i execute this lambda expression and get the desired output?RegardsBadal
Badal Kotecha
The problem is i do not now type T of IQueryable<T> at design time.. and i can not hardcode the typecasting and hence not able to apply "Where" method and passing this lambda expression to it. I get an object using reflection from entity model (PropertyInfo.GetValue()) whose runtime type is ObjectSet<entity> if i do the typecasting at design time.. I am able to query.. but how do i do that at rutime? as soon as i write the from prop in objet Where or object.Where(nc => nc.id == primaryKey).. it bombs... as it does not find Where implementation.RegardsBadal
Badal Kotecha
I think you will need to dynamically call your `Where` on your `ObjectSet<T>` using reflection. At that point you can pass it the expression tree that you constructed using my example.
Wallace Breza
@Badal Kotecha - I've updated my answer to include an example on how to call `Where` method on your IQueryable.
Wallace Breza
A: 

Thanks for your response.. Looks like this can solve my problem.. but I did not understand this part of your comment

"The lambda will have a runtime type of Expression> which you can then pass to any IQueryable implementation"

My next question is .. how do i execute this lambda expression (on ObjectSet where T is not known on compile time) and get the desired output?

Regards Badal

Badal Kotecha