C# Entity Framework:Linq 对孙子进行筛选并对父进行 Select
C# Entity Framework: Linq Filter on GrandChildren and Conduct a Select on the Parent
我们公司目前正在使用 Entity Framework Net Core 2.2 和 Sql Server
正在尝试查找购买了特定产品输入参数的所有不同客户。
当尝试执行 final select 时,它会将 b lambda 显示为 Product。我们需要最后出现的不同客户。
如何为不同的客户编写 EF Linq 查询?
var taxAgencyDistinctList = db.Customer
.SelectMany(b => b.Transactions)
.SelectMany(b => b.Purchases)
.Select(b => b.Product)
.Where(b => b.BKProduct == ProductInput)
.Select(b => b.).Distinct();
等价于SQL很简单:
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
公司更喜欢我们不使用 Linq 的方法 Sql,如果可能的话
资源:
var taxAgencyDistinctList = db.Purchases
.Include(p => p.Transaction).ThenInclude(t => t.Customer)
.Where(p => p.ProductId == ProductInput.ProductId)
.Select(b => b.Transaction.Customer).Distinct();
你可以从另一边走。
当您执行 select 时,linq 从该 selected 类型继续。在你的情况下是产品。
第二种方法是从客户开始,然后包括在内。然后在 where close check customer purcheses.any(m => m.ProductId == input.ProductId) 或类似的东西。
如果您使用内部联接,那么这应该可以正常工作。
var taxAgencyDistinctList = db.Customer
.Join(db.Transactions, customer => customer.customerId, transaction => transaction.customerid, (customer, transaction) => new
{
Customer = customer,
Transaction = transaction
})
.Join(db.Purchases, comb => comb.Transaction.PurchaseId, purchase => purchase.PurchaseId, (comb, purchase) => new
{
OldCombinedObject = comb,
Purchase = purchase
})
.Join(db.Product, comb => comb.OldCombinedObject.Transaction.ProductId, product => product.ProductId, (comb, product) => new
{
LastCombinedObject = comb,
Product = product
})
.Where(comb => comb.LastCombinedObject.OldCombinedObject.Transaction.BKProduct == ProductInput)
.Select(comb => comb.LastCombinedObject.OldCombinedObject.Customer).Distinct();
虽然您可能通过其他一些答案获得了您想要的数据,但您可能因追求的目标而过度补水(这意味着您对数据库的访问过多)。
".Any
" 是 EF 编写 "WHERE EXISTS
" 子句的方式。
这是对 EF 查询的尝试:
IEnumerable<Customer> justCustomersHydrated = db.Customer
.Where(p => p.Transactions.SelectMany(c => c.Purchases).Select(gc => gc.Product.Where(gc => gc.BKProduct == ProductInput).Any());
我使用“p”作为父级,“c”作为子级,“gc”作为孙级。你当然可以替换那些,但我试图在代码中显示意图。
您正在尝试(生成)SQL,看起来更像这样。
select c.customerId /* and c.AllOtherColumns */
from dbo.customer customer
WHERE EXISTS
(
SELECT 1 FROM dbo.Transactions transaction
inner join dbo.Purchases purchases
on purchases.PurchaseId = transaction.PurchaseId
inner join dbo.Product product
on transaction.ProductId = product.ProductId
where tra.BKProduct = @ProductInput
AND /* relationship to outer query */
transaction.customerid = customer.customerid
)
这将混合客户对象(客户对象的所有标量和无导航属性)。
您可以选择 select(客户的较少标量属性)....
您也可以只 select customerid(尽管通常 selecting 来自父 table 的所有列并不是太可怕,除非 table 有 many/many 列或某处的大数据 (image/varbinary(max)) 列。
看到这个答案:
Entity Framework - check whether has grandchild records
答案中有“新{”的地方是较不激进的 SELECT。
你真的需要加入采购吗? IE 是否有一些没有购买的交易,你想排除那些有内部连接的交易?如果没有,那么
select distinct c.customerId
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
就是
var cids = db.Transactions
.Where( t => t.Purchase.BKProduct = productImput )
.Select(t => new
{
t.Purchase.CustomerId,
t.Purchase.Customer.CustomerName
})
.Distinct();
我们公司目前正在使用 Entity Framework Net Core 2.2 和 Sql Server
正在尝试查找购买了特定产品输入参数的所有不同客户。 当尝试执行 final select 时,它会将 b lambda 显示为 Product。我们需要最后出现的不同客户。
如何为不同的客户编写 EF Linq 查询?
var taxAgencyDistinctList = db.Customer
.SelectMany(b => b.Transactions)
.SelectMany(b => b.Purchases)
.Select(b => b.Product)
.Where(b => b.BKProduct == ProductInput)
.Select(b => b.).Distinct();
等价于SQL很简单:
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
公司更喜欢我们不使用 Linq 的方法 Sql,如果可能的话
资源:
var taxAgencyDistinctList = db.Purchases
.Include(p => p.Transaction).ThenInclude(t => t.Customer)
.Where(p => p.ProductId == ProductInput.ProductId)
.Select(b => b.Transaction.Customer).Distinct();
你可以从另一边走。 当您执行 select 时,linq 从该 selected 类型继续。在你的情况下是产品。
第二种方法是从客户开始,然后包括在内。然后在 where close check customer purcheses.any(m => m.ProductId == input.ProductId) 或类似的东西。
如果您使用内部联接,那么这应该可以正常工作。
var taxAgencyDistinctList = db.Customer
.Join(db.Transactions, customer => customer.customerId, transaction => transaction.customerid, (customer, transaction) => new
{
Customer = customer,
Transaction = transaction
})
.Join(db.Purchases, comb => comb.Transaction.PurchaseId, purchase => purchase.PurchaseId, (comb, purchase) => new
{
OldCombinedObject = comb,
Purchase = purchase
})
.Join(db.Product, comb => comb.OldCombinedObject.Transaction.ProductId, product => product.ProductId, (comb, product) => new
{
LastCombinedObject = comb,
Product = product
})
.Where(comb => comb.LastCombinedObject.OldCombinedObject.Transaction.BKProduct == ProductInput)
.Select(comb => comb.LastCombinedObject.OldCombinedObject.Customer).Distinct();
虽然您可能通过其他一些答案获得了您想要的数据,但您可能因追求的目标而过度补水(这意味着您对数据库的访问过多)。
".Any
" 是 EF 编写 "WHERE EXISTS
" 子句的方式。
这是对 EF 查询的尝试:
IEnumerable<Customer> justCustomersHydrated = db.Customer
.Where(p => p.Transactions.SelectMany(c => c.Purchases).Select(gc => gc.Product.Where(gc => gc.BKProduct == ProductInput).Any());
我使用“p”作为父级,“c”作为子级,“gc”作为孙级。你当然可以替换那些,但我试图在代码中显示意图。
您正在尝试(生成)SQL,看起来更像这样。
select c.customerId /* and c.AllOtherColumns */
from dbo.customer customer
WHERE EXISTS
(
SELECT 1 FROM dbo.Transactions transaction
inner join dbo.Purchases purchases
on purchases.PurchaseId = transaction.PurchaseId
inner join dbo.Product product
on transaction.ProductId = product.ProductId
where tra.BKProduct = @ProductInput
AND /* relationship to outer query */
transaction.customerid = customer.customerid
)
这将混合客户对象(客户对象的所有标量和无导航属性)。
您可以选择 select(客户的较少标量属性).... 您也可以只 select customerid(尽管通常 selecting 来自父 table 的所有列并不是太可怕,除非 table 有 many/many 列或某处的大数据 (image/varbinary(max)) 列。
看到这个答案:
Entity Framework - check whether has grandchild records
答案中有“新{”的地方是较不激进的 SELECT。
你真的需要加入采购吗? IE 是否有一些没有购买的交易,你想排除那些有内部连接的交易?如果没有,那么
select distinct c.customerId
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
就是
var cids = db.Transactions
.Where( t => t.Purchase.BKProduct = productImput )
.Select(t => new
{
t.Purchase.CustomerId,
t.Purchase.Customer.CustomerName
})
.Distinct();