筛选然后包括三个嵌套层 [英] Filtering On ThenInclude Three Nested Levels down

查看:127
本文介绍了筛选然后包括三个嵌套层的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图向下过滤三个子级别,并仅查找PropertyMailingAddress.Status == True的子元素。

I am trying to filter three child levels down and find only child elements where PropertyMailingAddress.Status== True.

在PropertyMailingAddress下,它仍返回False值状态

It is still returning values which are False under PropertyMailingAddress.Status

如何将过滤器向下转换三级并使用thenInclude进行嵌套过滤?

How do I convert filter three levels down and conduct nested filtering with ThenInclude?

类结构为这样嵌套:


  1. 属性

  2. PropertyParty

  3. Party

  4. PartyMailingAddress

  5. PropertyMailingAddress <--状态应等于true(状态为== False的任何孙子PropertyMailingAddress节点应为从此嵌套的孙子分支中删除,请保留为True的PropertyMailingAddress节点)

  1. Property
  2. PropertyParty
  3. Party
  4. PartyMailingAddress
  5. PropertyMailingAddress <--- Status should equal true (Any grandchild PropertyMailingAddress nodes with Status == False, should be removed from this nested grandchild branch, keep the PropertyMailingAddress nodes which are True)





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的某种快捷方式,但是,包含所有属性通常会浪费处理能力,因为您不会

People tend to use Include as some kind of Shortcut for a Select. However, it is usually quite a waste of processing power to include all properties, because you won't use several of them or because you already know the value.

例如,一个有学生的学校,一个直接的一对多关系,每个学校的零个或多个学生,每个学生恰好就读一所学校,即外键SchoolId所指的学校。

Take for instance a School with Students, a straightforward one-to-many relation. Every School has zero or more Students, every Student attends exactly one School, namely the School that the foreign key SchoolId refers to.

因此,如果学校[10]有2000名学生,那么每个学生将拥有SchoolId的值等于10。如果使用其学生查询School [10],则该值[10]的传输将超过2000次。

So if School [10] has 2000 Students, then every Student will have a value for SchoolId equal to 10. If you query School [10] with its Students, you will be transferring this value [10] more than 2000 times. What a waste of processing power!


在实体框架中,使用 Select 查询数据,仅选择您实际计划使用的值。如果您打算更新所包含的数据,请仅使用 Include

In entity framework, use Select to query data, and only select the values that you actually plan to use. Only use Include if you plan to update the included data.

当然不要

回到您的问题


  • 每个属性都有零个或多个PropertyParties。

  • 每个PropertyParty都有零个或多个PropertyParties。

  • 每个属性都具有零个或多个PartyMailingAddresses

  • 每个PartyMailingAddress具有零个或多个PropertyMailingAddresses

  • 每个PropertyMailingAddress具有布尔属性Status

  • Every Property has zero or more PropertyParties.
  • Every PropertyParty has zero or more Properties.
  • Every Property has zero or more PartyMailingAddresses
  • Every PartyMailingAddress has zero or more PropertyMailingAddresses
  • Every PropertyMailingAddress has a Boolean property Status

您要查询所有属性(的多个属性),这些属性至少包含一个具有真实Status值的PropertyMailingAddress。

You want to query (several properties of) all Properties, that have deep inside at least one PropertyMailingAddress with a true Status value.

每当您有一个Item序列,其中每个Item都有一个OtherItems的子序列,并且想要像将其作为一个序列一样调查所有OtherItems时,请考虑使用SelectMany:

Whenever you have a sequence of Items where every Item has a subsequence of OtherItems, and you want to investigate all OtherItems as if it were one sequence, consider using 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(...)

现在结束只有那些具有深入内部至少具有一个真实的Status值。继续使用 Select (或如果您确实要: Include

So now you have only those Properties that deep inside have at least one true Status value. Continue the query with a Select (or if you really want: 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之外,Select的效率比Include更为有效,它为您提供了更大的自由来偏离数据库表如果需要的话。如果您不需要最终结果中的所有PropertyMailingAddresses,只需不要选择它们。如果只需要PropertyParties的总数,请使用 PropertyPartyCount = propertyParties.Count 。使用Select,返回的数据不必与数据库表相似。

Apart from that Select is more efficient than Include, it gives you more freedom to deviate from your database tables if needed. If you don't need all PropertyMailingAddresses in your end result, simply don't select them. If you only want the total number of PropertyParties, use PropertyPartyCount = propertyParties.Count. With Select the returned data does not have to be similar to your database tables.

这样做的好处是您可以隐藏数据库中的更改:只需更改Select,然后您的所有用户都不会注意到您已经更改了表的深层内容。

This has the advantage that you can hide changes in your database: simply change the Select, and all your users won't notice that deep inside you have changed your tables.

这篇关于筛选然后包括三个嵌套层的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆