如何在 .net core ef 上应用 thenInclude 条件?

Posted

技术标签:

【中文标题】如何在 .net core ef 上应用 thenInclude 条件?【英文标题】:How to apply thenInclude condition on above relations on .net core ef? 【发布时间】:2021-10-09 00:08:03 【问题描述】:

我有一些具有一对多关系的类别表。 让我们调用类 A、B 和 C,并假设 A 可以包含许多 B,B 可以与许多 C 相关。

并想象这是

的结果
select A.id, B.id, C.id, C.type 
from A 
left join B on B.a_id=A.id 
left join C on B.id=C.id
A.id B.id C.id C.type
1 1 1 f
1 1 2 f
1 1 3 g
1 2 4 g
1 2 5 g
2 3 6 h

在 ef 核心上,如果我执行这个 Linq Lambda

 var items = context.As.AsNoTracking()    // As, Bs, Cs, are the DbContext names and the ICollection's name on the Model definition
               .Include(i => i.Bs)
                 .ThenInclude(j => j.C.Where(k=>k.type=="f"));
return await Task.FromResult(items);

我得到 Bid=2 和空 ICollection Cs。

我希望那些不会出现,就像在内部连接中发生的那样。

有没有办法做到这一点?

提前谢谢你。


视觉表示如下。 我来了

As (result set)
|- 
|  |-A
|  | |-id=1
|  | |-Bs= 
|  | |     |-B
|  | |     | |-id=1
|  | |     | |-Cs= 
|  | |     | |     |-C
|  | |     | |     | |-id=1
|  | |     | |     | |-type="f"
|  | |     | |     |
|  | |     | |     |-C
|  | |     | |     | |-id=2
|  | |     | |     | |-type="f"
|  | |     | |
|  | |     |-B
|  | |     | |-id=2
|  | |     | |-Cs= 
|  |-A
|  | |-id=2
|  | |-Bs= 
|  | |     |-B
|  | |     | |-id=3
|  | |     | |-Cs= 

当我想要的时候

As (result set)
|- 
|  |-A
|  | |-id=1
|  | |-Bs= 
|  | |     |-B
|  | |     | |-id=1
|  | |     | |-Cs= 
|  | |     | |     |-C
|  | |     | |     | |-id=1
|  | |     | |     | |-type="f"
|  | |     | |     |
|  | |     | |     |-C
|  | |     | |     | |-id=2
|  | |     | |     | |-type="f"

【问题讨论】:

您需要在.Include(i => i.Bs)中添加相应的过滤器。 如果你熟悉 sql 语法,你也可以使用 join:var result=(from a in As join b in Bs on a.id equals b.a_id join c in Cs on b。 id 等于 c.b_id 其中 c.type=="f" select new a_id=a.id b_id=b.id, c_id=c.id ) @GuruStron 但如何? Bs 不能访问 C 属性,它只能访问 Cs,这是一个 ICollection @PabloFuenzalida Aid == 2 怎么样?它应该出现在结果中吗? @GuruStron yu 是对的,我正在修复它。谢谢 【参考方案1】:

过滤后的Include 仅适用于集合本身。随后的ThenInclude 不会过滤前面的Include。这就是我的意思:

context.As
    .Include(a => a.Bs) // Fully populates A.Bs
    .ThenInclude(b => b.Cs.Where(c => c.type == "f")); // Partly populates B.Cs

您希望Cs 上的过滤器也会过滤Bs,但Bs 仅受Bs 上过滤后的Include 影响,在您的情况下相当于:

context.As
    .Include(a => a.Bs.Where(b => b.Cs.Any(c => c.type == "f"))
    .ThenInclude(b => b.Cs.Where(c => c.type == "f"))

【讨论】:

更多关于过滤Includes here的范围和效果的细节。

以上是关于如何在 .net core ef 上应用 thenInclude 条件?的主要内容,如果未能解决你的问题,请参考以下文章

.net core EF Core 视图的应用

如何在 .NET EF Core 中实现自引用多对多关系

(17)ASP.NET Core EF基于数据模型创建数据库

如何使用 EF Core 代码优先迁移为 ASP.NET Core MVC 配置 N 层架构

具有 ASP.NET Core 3.0 和 EF Core 的多租户应用程序

非托管代码中的 ASP Net Core 1.1 和 EF 6 异常?