在 ThenInclude 三层嵌套的基础上进行过滤。
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在 ThenInclude 三层嵌套的基础上进行过滤。相关的知识,希望对你有一定的参考价值。
我试图向下过滤三个子级别,只找到 PropertyMailingAddress.Status== True 的子元素。
但它仍然在PropertyMailingAddress.Status下返回False的值。
如何将过滤三层向下转换,用ThenInclude进行嵌套过滤?
类结构是这样嵌套的。
- 属性
- 财产方
- 党
- 党员邮件地址
- PropertyMailingAddress
var result = await propertyRepository.GetAll()
.Include(pm => pm.PropertyParty).ThenInclude(x => x.Party).ThenInclude(x => x.PartyMailingAddress).ThenInclude(x => x.PropertyMailingAddress)
.Where (a=> a.PropertyParty.Any(x=> (x.Party.PartyMailingAddress.Any(z => z.PropertyMailingAddress.Any(h => h.Status.HasValue && h.Status.Value && h.Status == true))))
人们倾向于使用Include作为Select的某种快捷方式。然而,包含所有的属性通常是相当浪费处理能力的,因为你不会使用其中的几个属性,或者因为你已经知道其值。
以一个有学生的学校为例,这是一个直接的一对多关系。每个学校都有0个或多个学生,每个学生正好就读于一个学校,即外键SchoolId所指的学校。
所以如果学校[10]有2000个学生,那么每个学生的SchoolId的值就等于10。如果你查询学校[10]和它的学生,你将会把这个值[10]转移2000次以上。真是浪费处理能力啊!
在实体框架中,使用
Select
来查询数据,并且只选择您实际计划使用的值。只使用Include
如果你打算更新包含的数据。
当然,不要把 "包含 "当作 "选择所有属性 "的某种快捷方式来使用
回到你的问题
- 每个属性都有零个或多个属性方。
- 每个PropertyParty都有零个或多个Property。
- 每个属性都有零个或更多的PartyMailingAddresses。
- 每个PartyMailingAddress都有零个或多个PropertyMailingAddresses。
- 每个PropertyMailingAddress都有一个Boolean属性Status。
你想查询(几个属性的)所有属性,这些属性至少有一个具有真实状态值的PropertyMailingAddress。
当你有一个Item序列,其中每个Item都有一个OtherItems的子序列,而你想把所有的OtherItems当作一个序列来调查,可以考虑使用SelectMany。
var propertiesWithTrueStatus = propertyRepository.GetAll()
.Where(property => property.SelectMany(property => property.PropertyParties)
// result: one big sequence of all PropertyParties of all properties
.SelectMany(propertyParty => propertyParty.PartyMailingAddresses)
// result: one big sequence of all PartyMailingAddresses of all
// PropertyParties of all Properties
.SelectMany(partyMailingAddress => partyMailingAddress.PropertyMailingAddresses)
.Select(propertyMailingAddress => propertyMailingAddress.Status)
// result: one big sequence of all Statusses of all PropertyMailingAddresses
// of all ... of all Properties
// Keep only the true status values:
.Where(status => status)
// keep only the Properties that have at least one true Status value
.Any())
// end of Where(...)
所以现在你只有那些深藏在里面至少有一个真状态值的属性。继续查询 Select
(或者如果你真的想。Include
)
.Select(property => new
// Select only the properties that you actually plan to use
Id = property.Id,
Name = property.Name,
...
PropertyParties = property.PropertyParties.Select(propertyParty => new
// again only the properties that you plan to use:
Id = propertyParty.Id,
...
// no need to Select this, you already know the value
// PropertyId = propertyParty.PropertyId
PartyMailingAddresses = propertyParty.PartyMailingAddresses
.Select( partyMailingAddress => new ... )
.ToList(),
)
.ToList(),
);
除此以外,Select比Include更有效,它给了你更多的自由,如果需要的话,可以偏离你的数据库表。如果你不需要在你的最终结果中包含所有的PropertyMailingAddresses,干脆不要选择它们。如果你只想知道 PropertyParties 的总数,使用 PropertyPartyCount = propertyParties.Count
. 使用Select,返回的数据不一定要和你的数据库表相似。
这样做的好处是,你可以隐藏数据库中的变化:只需改变Select,你所有的用户都不会注意到你改变了你的表。
以上是关于在 ThenInclude 三层嵌套的基础上进行过滤。的主要内容,如果未能解决你的问题,请参考以下文章