组合相同输入类型的选择表达式

时间:2012-03-21 16:22:24

标签: c# linq expression

说,我在派生类中重写了这些属性。

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方法上获得例外

  

参数类型不匹配

1 个答案:

答案 0 :(得分:0)

我不知道从lambda表达式中的其他表达式树组装表达式树的方法,所以我认为你必须以编程方式构建树。这篇MSDN文章(How to: Use Expression Trees to Build Dynamic Queries)展示了如何使用表达式树API来构建表达式树。

在这种情况下,您需要一个new表达式,然后是三个属性赋值;我认为你不能在表达式树中做到这一点。你可以通过创建一个分配属性的构造函数来解决这个问题。