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
向Linq表达式添加方法调用,同时保留完整表达式_Linq_Lambda - Fatal编程技术网

向Linq表达式添加方法调用,同时保留完整表达式

向Linq表达式添加方法调用,同时保留完整表达式,linq,lambda,Linq,Lambda,如何在保持linq表达式的同时扩展它?我已经将其简化了很多(以避免粘贴页面)。例如,我使用可查询而不是可枚举,但解决方案就足够了,最终我需要将其作为表达式保留,同时添加方法调用 例如 var p1 = new Person() {Name = "RDA1", Age = 27}; var p2 = new Person() {Name = "RDA2", Age = 28}; var p3 = new Person() {Name = "RDA3"

如何在保持linq表达式的同时扩展它?我已经将其简化了很多(以避免粘贴页面)。例如,我使用可查询而不是可枚举,但解决方案就足够了,最终我需要将其作为表达式保留,同时添加方法调用

例如

        var p1 = new Person() {Name = "RDA1", Age = 27};
        var p2 = new Person() {Name = "RDA2", Age = 28};
        var p3 = new Person() {Name = "RDA3", Age = 29};

        var people = new[] {p1, p2, p3};


        Expression<Func<IEnumerable<Person>, IEnumerable<Person>>> filterExp
            = list => list.Take(2);


        Expression<Func<Person, int>> sortExp = l => l.Age;


        MethodCallExpression orderByCallExpression = Expression.Call(
            typeof (Enumerable),
            "OrderByDescending",
            new Type[] {typeof (Person), typeof (int)},
            filterExp.Parameters[0],
            sortExp); 

var combinedExpression = Expression.Lambda<Func<IEnumerable<Person>, IEnumerable<Person>>>
(filterExp.AddMethodCall(orderByCallExpression)); // made up AddMethodCall but you get the idea
var p1=newperson(){Name=“RDA1”,年龄=27};
var p2=newperson(){Name=“RDA2”,年龄=28};
var p3=newperson(){Name=“RDA3”,年龄=29};
var people=新[]{p1,p2,p3};
表达式过滤器exp
=列表=>list.Take(2);
表达式xp=l=>l.年龄;
MethodCallExpression orderByCallExpression=Expression.Call(
类型(可枚举),
“OrderByDescending”,
新类型[]{typeof(Person),typeof(int)},
filterExp.参数[0],
(XP);
var combinedExpression=Expression.Lambda
(filterExp.AddMethodCall(orderByCallExpression));//编了一个电话,但你明白了
在过去的几个小时里,我已经搜索了几十篇SO帖子,但我似乎无法找到答案,
如果我编译filterExp,我可以这样做,但必须同时保留表达式和最终结果表达式。

首先,您不需要将所有内容都切换到
IEnumerable
AsQueryable()
将允许您使用带有表达式树的测试集合:

var p1 = new Person() { Name = "RDA1", Age = 27 };
var p2 = new Person() { Name = "RDA2", Age = 28 };
var p3 = new Person() { Name = "RDA3", Age = 29 };

var people = new[] { p1, p2, p3 }.AsQueryable();
您已经有了一个良好的开端,您只需要在以下位置转换您正在使用的内容:

Expression<Func<IQueryable<Person>, IQueryable<Person>>> filterExp
    = list => list.Take(2);

Expression<Func<Person, int>> sortExp = l => l.Age;

MethodCallExpression orderByCallExpression = Expression.Call(
    typeof(Queryable),
    "OrderByDescending",
    new Type[] { typeof(Person), typeof(int) },
    filterExp.Body,
    sortExp);

var combinedExpression =
    Expression.Lambda<Func<IQueryable<Person>, IQueryable<Person>>>(
        orderByCallExpression, filterExp.Parameters[0]);

如果有人能解释如何以编程的方式构建它,“可能”会回答同样的问题。表达式filter=list=>list.Take(2.OrderBy)(p=>p.Age);如果您想执行逻辑列表=>list.OrderBy(p=>p.Age).Take(2);
var compiled = combinedExpression.Compile();
var res = compiled(people);

foreach (var r in res)
{
    // Do something
}