簡體   English   中英

C# Entity Framework Core,左連接中的內部選擇

[英]C# Entity Framework Core, Inner Select in Left Join

我想使用實體框架使以下 SQL Server 等效。 原來的SQL如下:

SELECT 
C.CustomerID, 
P.Title,
P.FirstName, 
P.LastName,
SOH.SalesOrderNumber,
SOH.SubTotal, 
SOH.TotalDue, 
SOH.OrderDate, 
SOH.ShipDate,
SOD.UnitPrice, 
SOD.LineTotal
FROM Sales.Customer AS C
INNER JOIN Person.Person AS P ON P.BusinessEntityID = C.PersonID
LEFT JOIN Sales.SalesOrderHeader AS SOH ON SOH.CustomerID = C.CustomerID
LEFT JOIN Sales.SalesOrderDetail AS SOD ON SOD.SalesOrderID = SOH.SalesOrderID
WHERE P.FirstName = 'Aaron'

這個 C# 似乎很接近,但它沒有做一個很好的連接,而是做了一個內部選擇

using (var db = new AdventureWorks2014Context())
{
    var queryable = db.Customer
        .Include(c => c.Person)
        .Include(c => c.SalesOrderHeader)
        .ThenInclude(soh => soh.SalesOrderDetail)
        .Where(x => x.Person.FirstName == name)
        .Select(c => new CustomerOrderDetails
        {
            CustomerId = c.CustomerId, 
            Title = c.Person.Title,
            FirstName = c.Person.FirstName, 
            LastName = c.Person.LastName, 
            SalesOrderHeaderLine = c.SalesOrderHeader.Select(soh => new CustomerSalesOrderHeaderLine
            {
                SubTotal = soh.SubTotal, 
                TotalDue = soh.TotalDue,
                OrderDate = soh.OrderDate,
                ShipDate = soh.ShipDate, 
                SalesOrderLine = soh.SalesOrderDetail.Select(so => new CustomerSalesOrderLine
                {
                    LineTotal = so.LineTotal, 
                    UnitPrice = so.UnitPrice
                })
            })
        });

    return queryable.ToList();
}

這是上面代碼產生的SQL

exec sp_executesql N'
SELECT 
[c].[CustomerID], 
[p].[Title], 
[p].[FirstName], 
[p].[LastName], 
[t].[SubTotal], 
[t].[TotalDue], 
[t].[OrderDate], 
[t].[ShipDate], 
[t].[SalesOrderID], 
[t].[LineTotal], 
[t].[UnitPrice], 
[t].[SalesOrderID0], 
[t].[SalesOrderDetailID]
FROM [Sales].[Customer] AS [c]
LEFT JOIN [Person].[Person] AS [p] ON [c].[PersonID] = [p].[BusinessEntityID]
LEFT JOIN (
    SELECT [s].[SubTotal], [s].[TotalDue], [s].[OrderDate], [s].[ShipDate], [s].[SalesOrderID], [s0].[LineTotal], [s0].[UnitPrice], [s0].[SalesOrderID] AS [SalesOrderID0], [s0].[SalesOrderDetailID], [s].[CustomerID]
    FROM [Sales].[SalesOrderHeader] AS [s]
    LEFT JOIN [Sales].[SalesOrderDetail] AS [s0] ON [s].[SalesOrderID] = [s0].[SalesOrderID]
) AS [t] ON [c].[CustomerID] = [t].[CustomerID]
WHERE [p].[FirstName] = @__name_0
ORDER BY [c].[CustomerID], [t].[SalesOrderID], [t].[SalesOrderID0], [t].[SalesOrderDetailID]',N'@__name_0 nvarchar(50)',@__name_0=N'Aaron'

是否可以編寫 C# 以便它只使用左連接,與我的原始查詢(在頂部)相同? 因為我不想要內部選擇。 這性能較差。 我不想要銷售訂單標題和詳細信息的內部選擇。 我想要它,因為我寫了原件(在頂部)。 純 SQL 的讀取更少的頁面並且執行更少的掃描。

請注意,我試圖將它編寫為與純 SQL 查詢一樣好(由於 brent ozar 的知識,我已經學到了大量知識)。 我知道它會給我我想要的東西,但我希望能夠編寫與我希望編寫 SQL 的方式一樣接近的 EF,因為當您的產品有數百萬行並且由於 EF 生成而速度緩慢時,這是不好的SQL 的臟轉儲。 在這種情況下,客戶掃描計數從 1 增加到 56,並且邏輯讀取增加了一倍,這不是那么好。

所以在 Svyatosalav Danyliv 回復之后,這似乎是 EF Core 的限制。

這是GitHub 上的已知問題。

無論我如何嘗試采用 EF,它都沒有自己編寫 SQL 好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM