说,我在派生类中重写了这些属性。
protected virtual Expression<Func<TEntity, long>> GetIDExpr { get; }
protected virtual Expression<Func<TEntity, string>> GetNameExpr { get; }
protected virtual Expression<Func<TEntity, long>> GetValueExpr { get; }
现在说我有这个班级
public class MyData
{
public long ID { get; set; }
public string Name { get; set; }
public long Value { get; set; }
}
现在,在基类中,我如何创建一个Expression<Func<TEntity, MyData>>
,在调用时,将填充每个字段并允许我创建一个返回IEnumerable<MyData>
的方法?
我想避免使用Invoke
,因为我只想从数据库中选择这3个字段。
注意:为了这个例子,将每个属性视为每次调用它时都返回Expression的相同实例,而不是每次都创建一个新实例。
修改
这是我的尝试,但没有效果:
public IEnumerable<MyData> GetAllData(IQueryable<TEntity> table) {
ParameterExpression parameter = Expression.Parameter(typeof(TEntity), "obj");
List<MemberBinding> bindings = new List<MemberBinding> {
Expression.Bind(typeof(MyData).GetProperty("ID"), GetIDExpr.Body),
Expression.Bind(typeof(MyData).GetProperty("Name"), GetNameExpr.Body),
Expression.Bind(typeof(MyData).GetProperty("Value"), GetValueExpr.Body),
};
var selector = Expression.MemberInit(Expression.New(typeof(MyData).GetConstructor(Type.EmptyTypes)), bindings);
var getBar = Expression.Lambda<Func<TEntity, MyData>>(selector, parameter);
return table.Select(getBar);
}
这里我在执行查询时得到一个ArgumentException,说
参数'obj'未绑定在指定的LINQ to Entities查询表达式中。
我认为这意味着使用.Body
表示值不会起作用,因为不再有参数。但是,如果我不使用.Body
,我会在.Bind
方法上获得例外
参数类型不匹配
答案 0 :(得分:0)
我不知道从lambda表达式中的其他表达式树组装表达式树的方法,所以我认为你必须以编程方式构建树。这篇MSDN文章(How to: Use Expression Trees to Build Dynamic Queries)展示了如何使用表达式树API来构建表达式树。
在这种情况下,您需要一个new
表达式,然后是三个属性赋值;我认为你不能在表达式树中做到这一点。你可以通过创建一个分配属性的构造函数来解决这个问题。