尝试按动态属性对 IQueryable 进行排序

本文关键字:IQueryable 排序 属性 动态 | 更新日期: 2023-09-27 17:57:15

我有以下问题,我想用一个Linq查询来解决:

我有一个数据库中的数据,我在实体框架的 Linq to SQL 的帮助下检索该数据库,然后我想应用排序。为此,我从客户端获得一个简单的字符串,然后动态映射到属性。之后,我只通过简单的跳过和获取来获得我需要显示的块。

现在的问题似乎是,我试图应用的操作并没有很好地结合在一起。我对 Linq 结果使用 IQueryable,因为我从数据库中获取数据。一旦 Linq 查询尝试执行,我就会收到错误,即使用 Linq to SQL,我无法使用"ToValue()",我需要像这样进行动态排序:

x.GetType().GetProperty(propertyName).GetValue(x, null);

我正在尝试做的事情是否可能,有人可以指出我正确的方向吗?我一直在用不同的方法玩弄似乎永远的东西,但无济于事。

这是我对一些变量进行硬编码的最后一种方法,但它也不起作用(它可能很笨拙,因为我已经研究它一段时间了)。

IQueryable<OA_FileUpload> result;
Expression<Func<MyObject, object>> orderBy = x => x.GetType().GetProperty(propertyName).GetValue(x, null);
result = Db.MyObject.Where(f => f.isSomething == true && f.isSomethingElse == false)
                                .OrderBy(orderBy)
                                .Skip(20)
                                .Take(20);

一旦我后来尝试对结果做某事,它就完全失败了。

尝试按动态属性对 IQueryable 进行排序

不,以你尝试的方式是不可能的。实体框架的引擎无法将x.GetType().GetProperty(propertyName).GetValue(x, null);转换为 SQL。您在SkipTake之前应用 OrderBy ,这是正确的方法,但这也意味着您的排序将被翻译为生成的 SQL 的一部分。

不过,您可以做的是逐步构建查询(即分几个步骤)。然后,您可以使用所需的条件添加排序。像这样:

IQueryable<OA_FileUpload> result = 
     Db.MyObject.Where(f => f.isSomething == true && f.isSomethingElse == false);
//Add your conditional sorting.
if(...) //Your first condition for sorting.
    result = result.OrderBy(....); //Your sorting for that condition.
else if(...) //Your second condition for sorting.
    result = result.OrderBy(....); //Your sorting for that condition.
//Now apply the paging.
    result = result.Skip(20).Take(20);

上面的 LINQ 仍作为单个查询转换和执行,但现在您可以添加所需的所有条件。