C# 使用表达式树在linq to实体中创建自定义排序依据

C# 使用表达式树在linq to实体中创建自定义排序依据,c#,.net,linq,entity-framework,expression-trees,C#,.net,Linq,Entity Framework,Expression Trees,我有一个映射的表,但在编译之后,可以在表中添加或删除其他列。我正在尝试提出一个linq查询,它将考虑这些新列。在这个场景中,我想按其中一个动态列排序。这就是我目前所拥有的 var queryableData = dc.wf_task_ext_attributes.AsQueryable(); ParameterExpression pe = Expression.Parameter(typeof(DateTime), "ExtValue105"); // The next line is wh

我有一个映射的表,但在编译之后,可以在表中添加或删除其他列。我正在尝试提出一个linq查询,它将考虑这些新列。在这个场景中,我想按其中一个动态列排序。这就是我目前所拥有的

var queryableData = dc.wf_task_ext_attributes.AsQueryable();
ParameterExpression pe = Expression.Parameter(typeof(DateTime), "ExtValue105");

// The next line is where it fails
MethodCallExpression orderByCallExpression = Expression.Call(
      typeof(Queryable),
       "OrderBy",
       new Type[] { queryableData.ElementType, queryableData.ElementType },
       queryableData.Expression,
       Expression.Lambda<Func<DateTime, DateTime>>(pe, new ParameterExpression[] { pe }));

IQueryable<string> results = queryableData.Provider.CreateQuery<string>
                         (orderByCallExpression);
var queryableData=dc.wf_task_ext_attributes.AsQueryable();
ParameterExpression pe=Expression.Parameter(typeof(DateTime),“ExtValue105”);
//下一行就是它失败的地方
MethodCallExpression orderByCallExpression=Expression.Call(
类型(可查询),
“订购人”,
新类型[]{queryableData.ElementType,queryableData.ElementType},
queryableData.Expression,
Lambda(pe,新参数表达式[]{pe});
IQueryable results=queryableData.Provider.CreateQuery
(orderByCallExpression);
它失败,并显示以下消息:

类型“System.Linq.Queryable”上的泛型方法“OrderBy”与提供的类型参数和参数不兼容。如果方法是非泛型的,则不应提供类型参数


我做错了什么?

queryableData
类型的
IQueryable
?似乎不是,因为您正在调用
CreateQuery

您对
表达式的调用。调用
似乎假定这是一个
IQueryable
。确保它是正确的


通过对查询进行硬编码,然后反编译生成的程序集,您可以了解如何正确构建LINQ查询。

您的代码尝试创建类似于
Queryable.OrderBy(queryableData.Expression,ExtValue105=>ExtValue105)的内容。
。我不知道你为什么会期望这样做

如果我正确理解了您的问题,您需要动态创建一个表达式,如
attribute=>attribute.ExtValue105
,然后您可以使用它调用
OrderBy()

代码可能看起来像这样(假设
queryableData
IQueryable
):

var parameter=Expression.parameter(typeof(Attribute),“Attribute”);
var property=Expression.property(参数“ExtValue105”);
var lambda=Expression.lambda(属性、参数);
可衡量的结果=
OrderBy(queryableData,(动态)lambda);

您可以手动使用
queryableData.Provider.CreateQuery()
来避免
动态调用,但这将更加复杂。

实体上是否有表示附加列的属性?不,列是在映射之后添加的。我不知道这将如何工作,您可以动态地按调用构建order,但必须具有现有属性才能使其有效。EF持有从属性到列的映射,但您没有属性,并且它不知道列的情况。queryableData是IQ类型的吗?似乎不是,因为您正在调用CreateQuery。这不是对您的问题的回答,但您看过动态Linq吗?对于这样的事情,它通常比手动滚动表达式树容易得多。不,它应该是
wf_task\u ext_attributes
类型,因为它是对linq的调用,用于实体。我知道CreateQuery的错误,但我并不担心这一点,因为代码从来没有碰到这一行。我尝试将lamba中的类型设置为
wf\u task\u ext\u attributes
,但它说它与类型
datetime
不匹配。好吧,如果查询源的类型是wf\u task\u ext\u attributes,为什么要将其视为datetime?(没有好的答案-我在试图理解您所犯的错误)。我在尝试按列排序,列的类型是datetime,而不是可查询的。@Smeegs我不这么认为,EF必须知道如何将表达式转换为SQL。
var parameter = Expression.Parameter(typeof(Attribute), "attribute");
var property = Expression.Property(parameter, "ExtValue105");
var lambda = Expression.Lambda(property, parameter);

IQueryable<Attribute> results =
    Queryable.OrderBy(queryableData, (dynamic)lambda);