Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.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# 表达式树OrderBy异常_C#_Expression Trees - Fatal编程技术网

C# 表达式树OrderBy异常

C# 表达式树OrderBy异常,c#,expression-trees,C#,Expression Trees,我有下面的代码片段,并得到一个错误,如下所述 string[] companies = { "Consolidated Messenger", "Alpine Ski House", "Southridge Video", "City Power & Light", "Coho Winery", "Wide World Importers", "Graphic Design Institute", "Adventure Works", "Humongous Insurance",

我有下面的代码片段,并得到一个错误,如下所述

string[] companies = {
 "Consolidated Messenger", "Alpine Ski House", "Southridge Video", "City Power & Light",
 "Coho Winery", "Wide World Importers", "Graphic Design Institute", "Adventure Works",
 "Humongous Insurance", "Woodgrove Bank", "Margie's Travel", "Northwind Traders",
 "Blue Yonder Airlines", "Trey Research", "The Phone Company",
 "Wingtip Toys", "Lucerne Publishing", "Fourth Coffee"
};

var exp = companies.AsQueryable<string>();

// Compose the expression tree that represents the parameter to the predicate.  
ParameterExpression pe = Expression.Parameter(typeof(string), "company");

// The IQueryable data to query.  
IQueryable<String> queryableData = companies.AsQueryable<string>();

MethodCallExpression orderByCallExpression1 = Expression.Call(
    typeof(Queryable),
    "OrderBy",
    new Type[] { queryableData.ElementType },
    Expression.Lambda<Func<string, string>>(pe, new ParameterExpression[] { pe })
  );
string[]公司={
“综合信使”、“高山滑雪屋”、“南岭视频”、“城市电力与照明”,
“Coho酒庄”、“全球进口商”、“平面设计学院”、“冒险作品”,
“巨额保险”、“伍德格罗夫银行”、“玛吉旅行”、“北风商人”,
“蓝色那边航空公司”、“特雷研究公司”、“电话公司”,
“翼尖玩具”、“卢塞恩出版”、“第四咖啡”
};
var exp=companys.AsQueryable();
//组合表示谓词参数的表达式树。
ParameterExpression pe=Expression.Parameter(typeof(string),“company”);
//要查询的IQueryable数据。
IQueryable queryableData=companys.AsQueryable();
MethodCallExpression orderByCallExpression1=表达式.Call(
类型(可查询),
“订购人”,
新类型[]{queryableData.ElementType},
表达式.Lambda(pe,新参数表达式[]{pe})
);
System.InvalidOperationException:类型上没有泛型方法“OrderBy” “System.Linq.Queryable”与提供的类型参数兼容 和争论。如果方法为,则不应提供类型参数 非通用。”

请说明这里有什么问题?

OrderBy方法有两个“问题”:它有重载和泛型。首先,您需要选择正确的重载:

var openOrderBy = typeof(Queryable)
    .GetMethods(BindingFlags.Static | BindingFlags.Public)
    .First(m => m.Name == "OrderBy" && m.GetParameters().Length == 2);
(注意:这里我使用基于参数计数的简单检查,您可以阅读更多)

然后需要将其绑定到具体类型:

var closedOrderBy = openOrderBy.MakeGenericMethod(
    typeof(string), // type of item in collection, TSource
    typeof(string)); // type returned by lambda, TKey
现在您可以在
表达式中使用
MethodInfo
。Call

var pe = Expression.Parameter(typeof(string), "company");

var orderByCall = Expression.Call(null, // for static methods
    closedOrderBy,
    companies.AsQueryable().Expression,
    Expression.Lambda<Func<string, string>>(pe, pe));
var pe=Expression.Parameter(typeof(string),“company”);
var orderByCall=Expression.Call(null,//对于静态方法
克洛斯多德比,
companys.AsQueryable()表达式,
Lambda(pe,pe));
您可以使用额外的lambda进行测试:

var result = Expression.Lambda<Func<IQueryable<string>>>(orderByCall)
    .Compile().Invoke().ToList();

result.ForEach(Console.WriteLine);
var result=Expression.Lambda(orderByCall)
.Compile().Invoke().ToList();
result.ForEach(Console.WriteLine);


更新:正如@Ivan Stoev在评论中所说,答案可以简化

var queryableData = companies.AsQueryable();
var pe = Expression.Parameter(typeof(string), "company");

var orderByCall = Expression.Call(typeof(Queryable),
    "OrderBy",
    new []{ queryableData.ElementType,
            queryableData.ElementType }, // <-- fix #1 select correct overload
    queryableData.Expression,            // <-- fix #2 pass first argument
    Expression.Lambda<Func<string, string>>(pe, pe)
  );
var queryableData=companys.AsQueryable();
var pe=表达式参数(typeof(string),“company”);
var orderByCall=Expression.Call(typeof(Queryable),
“订购人”,
新[]{queryableData.ElementType,
queryableData.ElementType},//OrderBy
方法有两个“问题”:它有重载,并且是泛型的。首先需要选择正确的重载:

var openOrderBy = typeof(Queryable)
    .GetMethods(BindingFlags.Static | BindingFlags.Public)
    .First(m => m.Name == "OrderBy" && m.GetParameters().Length == 2);
(注意:这里我使用基于参数计数的简单检查,您可以阅读更多)

然后需要将其绑定到具体类型:

var closedOrderBy = openOrderBy.MakeGenericMethod(
    typeof(string), // type of item in collection, TSource
    typeof(string)); // type returned by lambda, TKey
现在您可以在
表达式中使用
MethodInfo
。Call

var pe = Expression.Parameter(typeof(string), "company");

var orderByCall = Expression.Call(null, // for static methods
    closedOrderBy,
    companies.AsQueryable().Expression,
    Expression.Lambda<Func<string, string>>(pe, pe));
var pe=Expression.Parameter(typeof(string),“company”);
var orderByCall=Expression.Call(null,//对于静态方法
克洛斯多德比,
companys.AsQueryable()表达式,
Lambda(pe,pe));
您可以使用额外的lambda进行测试:

var result = Expression.Lambda<Func<IQueryable<string>>>(orderByCall)
    .Compile().Invoke().ToList();

result.ForEach(Console.WriteLine);
var result=Expression.Lambda(orderByCall)
.Compile().Invoke().ToList();
result.ForEach(Console.WriteLine);


更新:正如@Ivan Stoev在评论中所说,答案可以简化

var queryableData = companies.AsQueryable();
var pe = Expression.Parameter(typeof(string), "company");

var orderByCall = Expression.Call(typeof(Queryable),
    "OrderBy",
    new []{ queryableData.ElementType,
            queryableData.ElementType }, // <-- fix #1 select correct overload
    queryableData.Expression,            // <-- fix #2 pass first argument
    Expression.Lambda<Func<string, string>>(pe, pe)
  );
var queryableData=companys.AsQueryable();
var pe=表达式参数(typeof(string),“company”);
var orderByCall=Expression.Call(typeof(Queryable),
“订购人”,
新[]{queryableData.ElementType,

queryableData.ElementType},//为什么要尝试通过
MethodCallExpression
编写此代码?在“natural”中编写代码时会发生什么(s/ed)直接编写一个
OrderBy
调用?我们正在实现一个动态逻辑,使用表达式树,这是普通linq查询无法解决的。解决此类问题的最简单方法是编写执行此操作的静态lambda,然后查看生成的表达式,以查看每个不同的值是什么,以及它们是如何被调用的与您在这里所做的工作无关。您为什么要尝试通过
方法调用表达式
编写此代码?在“自然”中编写代码时会发生什么情况(s/ed)直接编写一个
OrderBy
调用?我们正在实现一个动态逻辑,使用表达式树,这是普通linq查询无法解决的。解决此类问题的最简单方法是编写执行此操作的静态lambda,然后查看生成的表达式,以查看每个不同的值是什么,以及它们是如何被调用的从您在这里所做的事情来看,您是对的,但前两个步骤并不是真正需要的-OP使用的
表达式.Call
重载正是针对这种情况,只有
类型[]
必须正确填充(
{typeof(string),typeof(string)}
)当然,在您添加的选择器(
companys.AsQueryable().Expression,
)之前缺少的参数,但在回答中没有提到。您是对的,但前两个步骤并不是真正需要的-OP使用的
表达式.Call
重载正是针对这种情况的,只是
类型[]
必须正确填充(
{typeof(string),typeof(string)}
),当然还有您添加的选择器前面缺少的参数(
companys.AsQueryable().Expression,
),但在回答中没有提到。