【问题标题】:How to apply thenInclude condition on above relations on .net core ef?如何在 .net core ef 上应用 thenInclude 条件?
【发布时间】: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);

我得到 B{id=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 是对的,我正在修复它。谢谢

标签: c# entity-framework linq .net-core lambda


【解决方案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的范围和效果的细节。
猜你喜欢
  • 1970-01-01
  • 2018-11-26
  • 1970-01-01
  • 2018-01-21
  • 1970-01-01
  • 2021-10-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多