This question is a continuation of this question here. If someone cares to know why I need to do things like this, you can find the rationale in that question. Not that it matters, really.
I need a method like this:
public virtual Expression<Func<T, object>> UpdateCriterion()
{
// this doesn't work because the compiler doesn't know if T has Id & CompanyId
return e => new { e.Id, e.CompanyId };
}
The problem is, there is no supertype for T
that I could use to pull out Id
and CompanyId
from, I have to do it dynamically. Thanks to the answer to that referenced question, I have successfully built and used this kind of method for one property (e => e.Id
), but I'm having issues implementing it for two. Just for visibility, the solution for one field is:
public virtual Expression<Func<T, object>> UpdateCriterion()
{
var param = Expression.Parameter(typeof(T));
var body = Expression.Convert(Expression.Property(param, "ID"), typeof(object));
return Expression.Lambda<Func<T, object>>(body, param);
}
I've been going nuts with this for over 6 hours... So, how do I solve this?
Try using reflection ?
Please not i don't have visual studio or any other IDE in front of me so the code my contain some bugs and typos
Also notes if you don't need
properties
, you may needfields
there are alsoGetField()
andGetFields()
look them around.The Body of this Lamba is a MemerInitExpression.
That was the easy part. The bigger Problem here is that you use an Anonymous Type in your Lambda.
If you use such an AnonymousType, the Compiler will inspect your code, detect the AnonymousType declaration and will create a Type like this on the fly.
And change your lambda into something like this.
Because you would like to create the lambda at runtime the f__AnonymousType0 type you need for the MemberInitExpression does not exist.
As you need an actual Type to create this Expression you have two options to get one.
1 - Write some generic classes like the Tuple class of the .NET Framework. Of cores this solution is limited to a maximum amount of properties.
pro: easy to create and use – con: limited property count.
2 - You could use Reflection.Emit and create a type at runtime http://www.codeproject.com/Articles/121568/Dynamic-Type-Using-Reflection-Emit
pro: unlimited property count – con: complicated
When you have a type you can use the Expression tree api you already know to crate the lambda
This creates an expression that looks like this