我想使用实体框架使以下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,并且逻辑读取次数增加了一倍,效果不佳。
答案 0 :(得分:0)