是否可以按 Entity Framework Core 中的连接列进行排序?
Is it possible to order by a joined column in Entity Framework Core?
我有一个通过 EF Core 映射的关系数据库,具有自定义的多对多 table,它在映射旁边保存排序顺序。
精简示例 类:
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;
}
我想获取 As 的列表(为简洁起见省略了一些标准进行过滤),然后按创建时间或连接 table 中指定的顺序进行排序。当按指定的排序 属性 排序时,结果将被过滤为仅 As linked 到一个特定的 B(尽管我认为这不会有任何区别)。
所以我有类似的东西
_dbContext.As.Include(a => a.Bs)
.ThenInclude(ab => ab.B)
.Where( a => a.Bs.Any(b => b.Id == 1))
.OrderBy(a => a.Created)
.ToList()
其中 returns 所有 As linked 到 ID 为 1 的 B,然后按创建日期排序。
现在我想 运行 对所有 As linked 到 B1 进行相同的查询,但按 link table.[=17= 的顺序进行排序]
在 SQL 中会很简单,因为我知道我已经加入 link table 并且可以按该列排序,但我找不到方法将其指定为 Entity Framework.
我可以将过滤后的 B Id 传递给子句,但这会为每一行构造一个 SQL 子查询,出于性能原因我想避免这种情况
.OrderBy(a => a.Bs.First(ab => ab.BId == 1).Ordering)
我曾尝试将匿名类型传递给 OrderBy 子句,希望 EF 将 Ordering 解释为连接的 Ordering 列,但它没有。
.OrderBy(a => new {Ordering = 0}.Ordering)
我尝试从联接 table 开始,然后向外工作,然后当一个 A linked 到多个 B 时会导致重复问题,然后使用 Distinct 删除以前的应用排序。
_dbContext.ABs
.Include(ab => ab.A)
.Include(ab => ab.B)
.OrderBy(ab => ab.Ordering)
.Select(ab => ab.A)
.Distinct()
我试过将 A 和 AB table 连接成一个匿名类型,这样我就可以从连接 table 中访问排序 属性,但那没有也不起作用,重复数据删除也有同样的问题。
_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()
我认为唯一的其他选择可能是将过滤后的数据具体化到内存中并在客户端上排序。但是我想避免这种情况,因为我应该能够直接在生成的 SQL.
中应用 ORDER BY
有什么方法可以告诉 Entity Framework 在连接 table 中按排序列进行排序而不创建子查询?
试试下面的查询,希望能理解你的问题。
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;
我有一个通过 EF Core 映射的关系数据库,具有自定义的多对多 table,它在映射旁边保存排序顺序。
精简示例 类:
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;
}
我想获取 As 的列表(为简洁起见省略了一些标准进行过滤),然后按创建时间或连接 table 中指定的顺序进行排序。当按指定的排序 属性 排序时,结果将被过滤为仅 As linked 到一个特定的 B(尽管我认为这不会有任何区别)。
所以我有类似的东西
_dbContext.As.Include(a => a.Bs)
.ThenInclude(ab => ab.B)
.Where( a => a.Bs.Any(b => b.Id == 1))
.OrderBy(a => a.Created)
.ToList()
其中 returns 所有 As linked 到 ID 为 1 的 B,然后按创建日期排序。
现在我想 运行 对所有 As linked 到 B1 进行相同的查询,但按 link table.[=17= 的顺序进行排序]
在 SQL 中会很简单,因为我知道我已经加入 link table 并且可以按该列排序,但我找不到方法将其指定为 Entity Framework.
我可以将过滤后的 B Id 传递给子句,但这会为每一行构造一个 SQL 子查询,出于性能原因我想避免这种情况
.OrderBy(a => a.Bs.First(ab => ab.BId == 1).Ordering)
我曾尝试将匿名类型传递给 OrderBy 子句,希望 EF 将 Ordering 解释为连接的 Ordering 列,但它没有。
.OrderBy(a => new {Ordering = 0}.Ordering)
我尝试从联接 table 开始,然后向外工作,然后当一个 A linked 到多个 B 时会导致重复问题,然后使用 Distinct 删除以前的应用排序。
_dbContext.ABs
.Include(ab => ab.A)
.Include(ab => ab.B)
.OrderBy(ab => ab.Ordering)
.Select(ab => ab.A)
.Distinct()
我试过将 A 和 AB table 连接成一个匿名类型,这样我就可以从连接 table 中访问排序 属性,但那没有也不起作用,重复数据删除也有同样的问题。
_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()
我认为唯一的其他选择可能是将过滤后的数据具体化到内存中并在客户端上排序。但是我想避免这种情况,因为我应该能够直接在生成的 SQL.
中应用 ORDER BY有什么方法可以告诉 Entity Framework 在连接 table 中按排序列进行排序而不创建子查询?
试试下面的查询,希望能理解你的问题。
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;