First, spec. We use MVC5, .NET 4.5.1, and Entity framework 6.1.
In our MVC5 business application we have a lot of repetitive CRUD code. My job is to \"automate\" mos
No, you cannot use dynamic in a Linq to Entities query. But you can build the Lambda Expression at runtime.
public virtual Expression<Func<TSubclass, object>> UpdateCriterion()
{
var param = Expression.Parameter(typeof(TSubclass));
var body = Expression.Convert(Expression.Property(param, "ID"), typeof(object));
return Expression.Lambda<Func<TSubclass, object>>(body, param);
}
If the TSubclass type does not have an ID property Expression.Property(param, "ID") will throw an exception.
Additionally you could use the MetadataWorkspace from your entity model to get the Primary Key column for TSubclass.
If you are defining the BaseEntity class, you could add a virtual read only property that returns the actual ID property. I beleive EF treats read only properties as "computed", so they are not stored to the db.
public abstract class BaseEntity<TSubclass> where TSubclass : BaseEntity<TSubclass>
{
public abstract object ID { get; }
public virtual Expression<Func<TSubclass, object>> UpdateCriterion()
{
return entity => entity.ID;
}
}
public partial class Foo : BaseEntity<Foo>
{
public Int32 FooId { get; set; }
public override object ID { get { return FooId; } }
}
Just a thought - I only tried compiling in LinqPad and checking the value of a call to UpdateCriterion. :)
Take a look at this answer. It uses reflection to get the ID Property. I think it solves your problem:
public static object GetPropValue(object src, string propName)
{
return src.GetType().GetProperty(propName).GetValue(src, null);
}
Then you replace your lambda expression by
return entity => GetPropValue(entity, "ID");
I've not tested, since I have no code fully working to test it. If it works please let us know.