实体框架核心对实体上的ICollection导航属性进行排序

时间:2020-07-31 21:40:30

标签: linq .net-core entity-framework-core

我们拥有的模型如下:我们有几个产品,每个产品都有一些属性以及一个ICollection<TierMatrix>。每个TierMatrix基本上是二维矩阵中的一行,并包含一个ICollection<Tier>,该矩阵在矩阵中构成条目。

产品

    Id // pk
    Code // int 
    ICollection<TierMatrix>

TierMatrix

    Id // pk
    ProductId // fk points to Product.Id
    Term // int defines a row on matrix 
    ICollection<Tier>

    Id // pk
    TierMatrixId // fk points to TierMatrix.Id
    Max // int value

我们当前的EF Core查询如下:

var products = await _context.Products
                  .Include(p => p.Matrices)
                  .ThenInclude(m => m.Tiers)
                  .ToListAsync();

问题是这不会对查询强加任何顺序,并且前端依赖于它们的特定顺序:

product.Code, tierMatrix.Term ASC, tier.Max DESC

我正在寻找解决此问题的最佳方法(最好的,因为它易于阅读且效率很高。)

到目前为止我已经尝试过:

  1. 当我尝试添加.OrderBy(...).ThenBy(...)时,出现运行时错误,表明该语句无法翻译。例如:

     var products = _context.Products
                 .Include(p => p.Matrices)
                     .ThenInclude(m => m.Tiers)
                     .OrderBy(p => p.Code)
                     .ThenBy(p => p.Matrices.Select(m => m.Term))
                     .ThenByDescending(p => p.Matrices.Select(m => m.Tiers.Select(t => t.Max)));
    
  2. 我试图将其切换为其他样式的查询:

     var products = from p in _context.Set<Product>()
                      join tm in _context.Set<TierMatrix>() on p.Id equals tm.ProductId
                      join t in _context.Set<Tier>() on tm.Id equals t.TierMatrixId
                      orderby p.Code, tm.Term ascending 
                      orderby t.Max descending                         
                      select new { p, tm, t };
    

    这使我获得了上面带有值并正确订购的产品,但结果中包含tmt值,但我只需要p。然后我可以做:

     var prod = products.ToList().Select(pr => p);
    

    但这似乎效率很低。如果我将查询的最后一行仅移至select new { p },则导航集合不会填充在p上。

  3. 在#2的查询中,我还使用from代替了join

     var products = from p in _context.Set<Product>().OrderBy(p => p.Code)
                from tm in _context.Set<TierMatrix>()
                              .Where(tm => tm.ProductId == p.Id)
                              .OrderBy(tm => tm.Term)
                from t in _context.Set<Tier>()
                              .Where(t => t.TierMatrixId == tm.Id)
                              .OrderByDescending(t => t.Max)
                select new { p, tm, t };
    

    这导致了与#2相同的问题。

我想念什么?

0 个答案:

没有答案