Dis*_*ile 5 .net c# linq-to-entities entity-framework-4
我注意到我的实体框架查询生成了一些非常难看的SQL.当我检查SQL时,即使非常简单的查询也会产生大量额外的JOIN.
我创建了一个简单的模型:
OrderID INT PK
OrderDate DATETIME
OrderID INT PK/FK
StatusID INT FK
StatusID INT PK
说明NVARCHAR(50)
从模型中,订单可以包含0或1个订单标题.标头将具有1种状态类型.
我创建了以下查询:
var orders = from o in db.Orders
where o.OrderID == 1
select new
{
Order = o,
Status = o.OrderHeader.Status
};
Run Code Online (Sandbox Code Playgroud)
由此生成的SQL看起来像:
SELECT
[Extent1].[OrderID] AS [OrderID],
[Extent1].[OrderDate] AS [OrderDate],
[Extent4].[StatusID] AS [StatusID],
[Extent4].[Description] AS [Description]
FROM [dbo].[Orders] AS [Extent1]
LEFT OUTER JOIN [dbo].[OrderHeaders] AS [Extent2] ON [Extent1].[OrderID] = [Extent2].[OrderID]
LEFT OUTER JOIN [dbo].[OrderHeaders] AS [Extent3] ON [Extent2].[OrderID] = [Extent3].[OrderID]
LEFT OUTER JOIN [dbo].[StatusTypes] AS [Extent4] ON [Extent3].[OrderID] = [Extent4].[OrderID]
WHERE 1 = [Extent1].[OrderID]
Run Code Online (Sandbox Code Playgroud)
如您所见,查询中有两个不必要的左连接.为什么SQL会像这样生成?我在质疑这个错误吗?我不应该在查询中使用导航属性吗?
我是否需要在查询本身中编写联接,以便它不会为我生成额外的连接?当我使用连接编写查询时,生成的SQL没有任何额外的JOIN,但LINQ to Entities查询更加丑陋/更详细:
var orders = from o in db.Orders
join h in db.OrderHeaders on o.OrderID equals h.OrderID into orderHeader
from h in orderHeader.DefaultIfEmpty()
join s in db.StatusTypes on h.StatusID equals s.StatusID into statusType
from s in statusType.DefaultIfEmpty()
where o.OrderID == 1
select new
{
o,
s
};
Run Code Online (Sandbox Code Playgroud)
这会在没有额外连接的情况下生成SQL,但从C#端看起来更加丑陋.
有人知道如何解决这个问题吗?
实体框架生成的 SQL 在许多情况下都没有问题,但肯定有一些情况会让您对生成的 SQL 感到不满。
首先,你真的在乎吗?它是否会导致性能问题(可能不会),或者如果您将其投入生产,您背后是否有 DBA 会向您开枪?:-)
如果你能忍受它,就不要打扰。否则,您将必须监视为您的查询生成的 SQL,并调整您的 linq 查询,或者诉诸存储过程或其他数据访问方式(或者可能切换 ORM...)。
编辑:当然,这个特殊情况显然仍然是 EF 4 中的一个错误......
| 归档时间: |
|
| 查看次数: |
2011 次 |
| 最近记录: |