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

本文关键字:选择 表达式 类型 输入 组合 | 更新日期: 2023-09-27 18:28:37

比方说,我有这些属性,它们在派生类中被重写。

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个字段。

注意:为了这个例子,将每个属性视为每次调用它都返回表达式的相同实例,而不是每次创建一个新实例

编辑:

这是我的尝试,但没有奏效:

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方法上得到一个异常

参数类型与不匹配

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

我不知道如何从lambda表达式中的其他表达式树组装表达式树,所以我认为您必须以编程方式构建树。这篇MSDN文章(如何:使用表达式树来构建动态查询)展示了如何使用表达式树API来构建表达式树。

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