首页 > 解决方案 > C# 实体框架:Linq 过滤 GrandChildren 并使用属性对父级进行选择

问题描述

我们公司目前正在使用Entity Framework Net Core 2.2 with Sql Server

试图找到购买了某个 Product Input Parameter 的所有 Distinct 客户。编写了以下 EF Linq 查询以获取不同的客户。

后来另一个问题出现了,我们如何获得客户的更多(导航)属性?Include应该放在Where之前还是之后?有关系吗?运行 SQL Profiler 时,它注意到查询没有任何区别。我只是想确定在某些情况下 Include here 的位置是否重要?

select distinct c.customerName
from dbo.customer customer
inner join dbo.Transactions transaction
    on transaction.customerid = customer.customerid
inner join dbo.Purchases purchases
    on purchases.PurchaseId = transaction.PurchaseId
inner join dbo.Product product 
    on transaction.ProductId = product.ProductId
where tra.BKProduct = @ProductInput

原始解决方案: C# Entity Framework:Linq Filter on GrandChildren 并在 Parent 上进行 Select

var customerData = db.Customer
                      .Where(p => p.Transactions.SelectMany(c => c.Purchases).Select(gc => gc.Product.Where(gc => gc.BKProduct == ProductInput).Any());

另一个问题出现了,我们需要获取更多的客户(导航)属性。

备选方案 1:

var customerData = db.Customer
                      .Include(c=>c.CustomerType)
                      .Include(c=>c.CustomerAddress)
                      .Where(p => p.Transactions.SelectMany(c => c.Purchases).Select(gc => gc.Product.Where(gc => gc.BKProduct == ProductInput).Any());

备选方案 2:

var customerData = db.Customer
                      .Where(p => p.Transactions.SelectMany(c => c.Purchases).Select(gc => gc.Product.Where(gc => gc.BKProduct == ProductInput).Any())
                      .Include(c=>c.CustomerType)
                      .Include(c=>c.CustomerAddress)

标签: c#.netentity-frameworklinq.net-core-2.2

解决方案


在这种特定情况下,它可能无关紧要。

由于 c# "Include" 是关于生成的 sql 的 SELECT 和 JOIN。

但是,您不想将“没关系”用作笼统的陈述。

请参阅下面的答案(以及总体问题和其他答案)。

LINQ 函数的顺序是否重要?

当您开始输入诸如 Where 和 OrderBy之类的内容时,操作顺序可能很重要。

总是查看生成的 sql 并问自己“看起来合理吗”?(你已经从你的问题中做到了:) ..我主要为未来的读者提到这一点)

因此,在这种特定情况下,这是一种偏好。我通常把.Where 最后。因此,您的第一个示例将符合我的个人喜好。

对于一些“进一步调查”,请查看以下内容:https ://weblogs.asp.net/dixin/introducing-linq-3-waht-is-functional-programming


推荐阅读