我想知道为什么Entity框架会生成如此低效的SQL查询。在我的代码中,我期望WHERE对INCLUDE采取行动:
db.Employment.Where(x => x.Active).Include(x => x.Employee).Where(x => x.Employee.UserID == UserID)
但我最终得到了一个双SQL连接:
SELECT [x].[ID], [x].[Active], [x].[CurrencyID], [x].[DepartmentID], [x].[EmplEnd], [x].[EmplStart], [x].[EmployeeID], [x].[HolidayGroupID], [x].[HourlyCost], [x].[JobTitle], [x].[ManagerID], [x].[WorkScheduleGroupID], [e].[ID], [e].[Active], [e].[Address], [e].[BirthDate], [e].[CitizenshipID], [e].[City], [e].[CountryID], [e].[Email], [e].[FirstName], [e].[Gender], [e].[LastName], [e].[Note], [e].[Phone], [e].[PostalCode], [e].[TaxNumber], [e].[UserID]
FROM [Employment] AS [x]
INNER JOIN [Employee] AS [x.Employee] ON [x].[EmployeeID] = [x.Employee].[ID]
INNER JOIN [Employee] AS [e] ON [x].[EmployeeID] = [e].[ID]
WHERE ([x].[Active] = 1) AND ([x.Employee].[UserID] = @__UserID_0)
我发现这个查询会创建更好的SQL:
db.Employment.Where(x => x.Active).Where(x => x.Employee.UserID == UserID)
SELECT [x].[ID], [x].[Active], [x].[CurrencyID], [x].[DepartmentID], [x].[EmplEnd], [x].[EmplStart], [x].[EmployeeID], [x].[HolidayGroupID], [x].[HourlyCost], [x].[JobTitle], [x].[ManagerID], [x].[WorkScheduleGroupID]
FROM [Employment] AS [x]
INNER JOIN [Employee] AS [x.Employee] ON [x].[EmployeeID] = [x.Employee].[ID]
WHERE ([x].[Active] = 1) AND ([x.Employee].[UserID] = @__UserID_0)
但是,这里的问题是没有从DB中检索引用的实体。
为什么两个代码不能生成相同的SQL?
答案 0 :(得分:4)
SQL不同,因为声明不同。
实体框架确实产生效率低下的TSQL,它始终具有。通过抽象出具有良好性能的SQL所必需的微妙之处,并用“腰带和大括号”替换它们几乎总是可以替代它,从而牺牲实用性能。
如果您需要良好的性能,请自行编写SQL。 Dapper对我很有用。您无法真实地期望“一刀切”的解决方案能够为您的特定情况提供最佳代码。您可以全面或在您需要的地方执行此操作。
除非您有大量或特定的性能要求,否则请使用最简单的方法。如果需要将查询调整到数据库,您将学习数据库引擎的详细信息并自行实现查询。如果您期望Entity Framework的下一次迭代成为神奇的子弹,它允许您以最少的知识快速,高效地进行SQL数据访问,祝您好运。
P.S。
偏离主题,但NoSQL可能不是答案,只是一个不同类别的数据库。