[英]C# Entity Framework: Linq Filter on GrandChildren and Conduct a Select on the Parent with Attributes
[英]C# Entity Framework: Linq Filter on GrandChildren and Conduct a Select on the Parent
我們公司目前正在使用 Entity Framework Net Core 2.2 和 Sql 服務器
試圖找到所有購買了某個產品輸入參數的不同客戶。 當試圖做最終的 select 時,它顯示 b lambda 作為產品。 我們需要不同客戶最后出現。
如何編寫 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
資源:
Net Core:Entity Framework ThenInclude with Projection Select
雖然您可能會通過其他一些答案獲得您想要的數據,但您可能對您所追求的東西過度補充(這意味着您對數據庫的影響太大)。
“ .Any
” 是編寫“ WHERE EXISTS
”子句的EF 方式。
這是對 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
)
這將水合客戶 object(客戶對象的所有標量和無導航屬性)。
或者,您可以 select(客戶的較少標量屬性)...。您也可以只 select 客戶 ID(盡管通常從父表中選擇所有列並不太可怕,除非該表有很多/很多列或很大data (image/varbinary(max)) 列在某處。
看到這個答案:
對於不太激進的 SELECT,該答案具有“新 {”。
如果您的 go 帶有內部連接,那么這應該可以正常工作。
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();
你真的需要加入購買嗎? 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();
var taxAgencyDistinctList = db.Purchases
.Include(p => p.Transaction).ThenInclude(t => t.Customer)
.Where(p => p.ProductId == ProductInput.ProductId)
.Select(b => b.Transaction.Customer).Distinct();
您可以從另一側 go。 當您執行 select 時,linq 從該選定類型繼續。 在您的情況下,這是產品。
第二種方法是從客戶和 go 開始,包括。 然后在 where close check customer purcheses.any(m => m.ProductId == input.ProductId) 或類似的東西。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.