使用表达式树在linq到实体中创建自定义顺序

时间:2014-11-14 14:50:17

标签: 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 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);

它没有收到以下消息:

  

没有通用的方法&#39; OrderBy&#39; on type&#39; System.Linq.Queryable&#39;与提供的类型参数和参数兼容。如果方法是非泛型的,则不应提供类型参数。

我做错了什么?

2 个答案:

答案 0 :(得分:0)

类型为queryableData的{​​{1}}?似乎不是因为你打电话给IQueryable<DateTime>

您对CreateQuery<string>的来电似乎认为这是Expression.Call。确保它是。

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

答案 1 :(得分:0)

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

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

代码看起来像这样(假设queryableDataIQueryable<Attribute>):

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

您可以手动使用queryableData.Provider.CreateQuery()来避免dynamic来电,但这样会更复杂。