使用表达式树在Linq中创建自定义订单到实体[英] Using expression trees to create a custom order by in linq to entities

本文是小编为大家收集整理的关于使用表达式树在Linq中创建自定义订单到实体的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我有一个映射的表,但是在编译了其他列后,可以从表中添加或删除.我正在尝试提出一个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);

以下消息失败:

type'system.linq.queryable'上的无通用方法'orderby'与所提供的类型参数和参数兼容.如果该方法是非生成的,则不得提供类型的参数.

我在做什么错?

推荐答案

是IQueryable<DateTime>类型的queryableData?似乎不是因为您打电话CreateQuery<string>.

您对Expression.Call的呼叫似乎假设这是IQueryable<DateTime>.确保它是.

您可以通过硬编码查询然后对结果组件进行刻度来找到如何正确构建LINQ查询.

其他推荐答案

您的代码试图创建Queryable.OrderBy(queryableData.Expression, ExtValue105 => ExtValue105)之类的东西.我不知道为什么您会期望它能起作用.

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

代码看起来像这样(假设queryableData是IQueryable<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呼叫,但这会更复杂.

本文地址:https://www.itbaoku.cn/post/1556990.html

问题描述

I have a table that's mapped, but after compile additional columns can be added or removed from the table. I'm trying to come up with a linq query that will take those new columns into account. In this scenario, I want to order by one of those dynamic columns. This is what I have so far.

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

It's failing with the following message:

No generic method 'OrderBy' on type 'System.Linq.Queryable' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic.

What am I doing wrong?

推荐答案

Is queryableData of type IQueryable<DateTime>? Seems not to be since you are calling CreateQuery<string>.

Your call to Expression.Call seems to assume that this is an IQueryable<DateTime>. Make sure that it is.

You can find out how to correctly build a LINQ query by hard-coding the query and then decompiling the resulting assembly.

其他推荐答案

Your code tries to create something like Queryable.OrderBy(queryableData.Expression, ExtValue105 => ExtValue105). I have no idea why would you expect that to work.

If I understand your question correctly, you need to dynamically create an expression like attribute => attribute.ExtValue105 and then you can use that to call OrderBy().

The code could look something like this (assuming queryableData is IQueryable<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);

You could use queryableData.Provider.CreateQuery() manually to avoid the dynamic call, but that would be more complicated.