简体   繁体   English

是否可以通过 Entity Framework Core 中的连接列进行排序?

[英]Is it possible to order by a joined column in Entity Framework Core?

I've got a relational database mapped via EF Core with a custom many to many table which holds a sort order alongside the mapping.我有一个通过 EF Core 映射的关系数据库,其中包含一个自定义的多对多表,该表在映射旁边包含排序顺序。

Stripped down example classes:精简示例类:

class A 
{
    int Id;
    IEnumerable<AB> Bs;
    DateTime Created;
}

class B 
{
    int Id;
    IEnumerable<AB> As
}

class AB 
{
    int AId;
    A A;
    int BId;
    B B;
    int Ordering;
}

I want to get a list of As (filtered by some criteria omitted for brevity) and then ordered, either by the created time or by the ordering specified in the join table.我想获得一个 As 列表(为简洁起见省略了一些标准进行过滤),然后按创建时间或连接表中指定的顺序进行排序。 When ordering by the specified Ordering property the results will be filtered to only As linked to one particular B (although I don't think that should make any difference).当按指定的 Ordering 属性排序时,结果将被过滤为仅 As 链接到一个特定的 B (尽管我认为这不会有任何区别)。

So I have something like所以我有类似的东西

_dbContext.As.Include(a => a.Bs)
             .ThenInclude(ab => ab.B)
             .Where( a => a.Bs.Any(b => b.Id == 1))
             .OrderBy(a => a.Created)
             .ToList()

which returns all As linked to B with Id 1, and then sorted by their created date.它返回所有链接到 ID 为 1 的 B 的 As,然后按它们的创建日期排序。

Now I want to run the same query for all As linked to B1 but order by the Ordering from the link table.现在我想对链接到 B1 的所有 As 运行相同的查询,但按链接表中的 Ordering 进行排序。

In SQL it would be simple since I know I have joined on the link table and could just order by that column, but I can't find a way to specify that to Entity Framework.在 SQL 中,这很简单,因为我知道我已经加入了链接表并且可以按该列进行排序,但我找不到将其指定给 Entity Framework 的方法。

I can pass the filtered B Id to the clause, but that constructs a SQL subquery for every single row, which I want to avoid for performance reasons我可以将过滤后的 B Id 传递给子句,但这会为每一行构造一个 SQL 子查询,出于性能原因我想避免这种情况

.OrderBy(a => a.Bs.First(ab => ab.BId == 1).Ordering)

I've tried passing an anonymous type to the OrderBy clause in the hope that EF would interpret Ordering as the joined Ordering column, but it didn't.我曾尝试将匿名类型传递给 OrderBy 子句,希望 EF 将 Ordering 解释为连接的 Ordering 列,但事实并非如此。

.OrderBy(a => new {Ordering = 0}.Ordering)

I've tried starting from the join table and working outwards instead, which then causes issues with duplication when one A is linked to multiple Bs, and using Distinct then removes the previously applied ordering.我已经尝试从连接表开始并向外工作,然后当一个 A 链接到多个 B 时会导致重复问题,然后使用 Distinct 删除之前应用的顺序。

_dbContext.ABs
          .Include(ab => ab.A)
          .Include(ab => ab.B)
          .OrderBy(ab => ab.Ordering)
          .Select(ab => ab.A)
          .Distinct()

I've tried joining the A and AB tables into an anonymous type so that I have access to the ordering property from the join table, but that didn't work either, same issue with deduplication.我已经尝试将 A 和 AB 表连接成匿名类型,以便我可以访问连接表中的排序属性,但这也不起作用,重复数据删除也有同样的问题。

_dbContext.As.Join( _dbContext.ABs, a => a.Id, ab => ab.AId, (a, ab) => new {a, ab})
             .Where( x => x.ab.BId = 1)
             .OrderBy( x => x.ab.Ordering)
             .Select(x => x.A)
             .Distinct()

I think the only other option might be to materialise the filtered data into memory and sort on the client.我认为唯一的其他选择可能是将过滤后的数据具体化为 memory 并在客户端上排序。 But I want to avoid that when I should just be able to apply ORDER BY directly in the generated SQL.但是我想避免这种情况,因为我应该能够直接在生成的 SQL 中应用 ORDER BY。

Is there any way I can tell Entity Framework to order by the Ordering column in the join table without creating subqueries?有什么方法可以让实体框架在不创建子查询的情况下按连接表中的 Ordering 列进行排序?

Try the following query, I hope understand your question.尝试以下查询,希望能理解您的问题。

var query = 
    from a in _dbContext.As
    from ab in _dbContext.ABs
        .Where(ab => ab.AId == ab.AId)
        .Where(ab => ab.BId == 1)
        .Orderby(ab => ab.Ordering)
        .Take(1)
    orderby ab.Ordering
    select a;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM