Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 组合相同输入类型的select表达式_C#_Linq_Expression - Fatal编程技术网

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);
}