C# 组合相同输入类型的select表达式
比如说,我有这些属性,它们在派生类中被重写C# 组合相同输入类型的select表达式,c#,linq,expression,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>>
protected virtual Expression<Func<TEntity, long>> GetIDExpr { get; }
protected virtual Expression<Func<TEntity, string>> GetNameExpr { get; }
protected virtual Expression<Func<TEntity, long>> GetValueExpr { get; }
现在,在基类中,如何创建一个表达式
,当调用该表达式时,它将填充每个字段,并允许我创建一个返回IEnumerable
的方法
我希望避免使用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);
}
public IEnumerable GetAllData(IQueryable表){
ParameterExpression参数=表达式参数(typeof(tenty),“obj”);
列表绑定=新列表{
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选择器=Expression.MemberInit(Expression.New(typeof(MyData).GetConstructor(Type.EmptyTypes)),绑定);
var getBar=Expression.Lambda(选择器,参数);
返回表。选择(getBar);
}
在这里,当执行查询时,我得到一个ArgumentException,表示
参数“obj”未绑定在指定的LINQ到实体查询表达式中
我假设这意味着对值表达式使用.Body
将不起作用,因为不再有参数。但是,如果我不使用.Body
,我会在.Bind
方法上得到一个异常
参数类型不匹配
我不知道如何从lambda表达式中的其他表达式树组装表达式树,因此我认为您必须以编程方式构建该树。这篇MSDN文章()展示了如何使用表达式树API构建表达式树
在这种情况下,需要一个
新的表达式,后跟三个属性赋值;我认为在表达式树中无法做到这一点。您可以通过创建一个分配属性的构造函数来解决这个问题。我不知道如何从lambda表达式中的其他表达式树组装表达式树,因此我认为您必须以编程方式构建树。这篇MSDN文章()展示了如何使用表达式树API构建表达式树
在这种情况下,需要一个新的表达式,后跟三个属性赋值;我认为在表达式树中无法做到这一点。您可以通过创建一个分配属性的构造函数来解决这个问题。LINQ中只支持无参数构造函数来分配实体。我知道那会发生的。有没有可能合并Expression.Assign语句?LINQ to实体中只支持无参数构造函数。我知道那会发生的。有没有可能合并表达式。赋值语句?
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);
}