【问题标题】:How to order a IQueryable list of parent objects by a value in it's childs list如何按子列表中的值对父对象的 IQueryable 列表进行排序
【发布时间】:2020-10-03 22:38:29
【问题描述】:

我正在尝试根据特定规范 TypeId 的 TextValue 根据复杂对象的子列表对复杂对象的父列表进行排序。

我有以下课程:

public class Product
{
    public long Id {get;set;}
    public string Name {get;set;}
    public List<Specification> Specifications {get;set;}
}

public class Specification
{
    public long Id {get;set;}
    public long TypeId {get;set;}
    public string TextValue {get;set;}
}

我想根据产品的特定规格对我的产品进行分类。 示例用例:根据 TypeId = 3 的规范的 TextValue 对产品进行排序。(一个产品只能有一个 TypeId 为 3 的规范)

我的产品列表如下所示:

IQueryable<Product> productQuery = _context.Products.Include("Specifications");

SortTypeId 是我要订购产品列表的规范类型。

这是我尝试做的:

productQuery = productQuery
.OrderBy(pq => pq.Specifications
.OrderBy(s => s.TypeID == SortTypeID ? Int32.MinValue : s.Id)
.ThenBy(v => v.TextValue));

这给出了以下异常:

System.ArgumentException: 'DbSortClause expressions must have a type that is order comparable.
Parameter name: key'

我还尝试通过使用 Indexof 的 sortedProductIds 列表对 IQueryable 进行排序,但这也不起作用(延迟加载的 IQueryable 不支持 IndexOf)。

【问题讨论】:

  • 我认为,您可以使用.where(x=&gt;xSpecifications.Any(y=&gt;y.TypeID == 3)) 来过滤规格,因此在过滤后您可以在产品和规格之间建立一对一的关系。并选择一个包含new {product, specification} 的匿名对象并使用orderby specification.TextValue

标签: c# linq sorting sql-order-by iqueryable


【解决方案1】:

既然你说一个产品只能有一个SortTypeID类型的规格,那么如果你在查询中加入那个规格并按它订购呢?

这是我尝试使用查询语法建议的一些示例。

from p in _context.Products.Include("Specifications")
join orderSpec in _context.Specifications on new { ProductID = p.Id, TypeID = 3 }
                                    equals new { ProductID = orderSpec.ProductId, TypeID = orderSpec.TypeID } into os 
from orderSpec in os.DefaultIfEmpty() 
orderby orderSpec != null ? orderSpec.TextValue : p.Id
select p

希望对你有帮助!

【讨论】:

  • 一个产品可以有一个规格列表,例如 TypeId 为 1,2,3,4。我想根据 TypeId 3 的产品规范中的 TextValue 订购产品列表。
  • 我稍微改了一下,让它更清楚,我认为应该这样做。
  • 感谢您的回答 devcrp 排序工作,我还有一个问题。我怎样才能从没有 TypeID 3 规范的 lambda 表达式中取回产品?
  • @PatrickMan 试试那个,我刚刚又编辑了一遍。基本上你需要做一个left join:stackoverflow.com/a/3413732/11350283
  • 完美运行,我需要在您的查询中更改的唯一内容是空检查。我将 p.Id (long) 更改为字符串。
猜你喜欢
  • 1970-01-01
  • 2010-11-07
  • 1970-01-01
  • 2011-07-17
  • 2011-11-20
  • 1970-01-01
  • 2020-10-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多