我想知道如何改进EF的查询生成示例
我有一个DbSet ItemControllers
Linq代码是:
ItemController.FirstOrDefault(x=>x.Name=="Acl")
// sql生成的euqilent Sql是
exec sp_executesql N'SELECT
[Limit1].[Id] AS [Id],
[Limit1].[Name] AS [Name],
[Limit1].[ShortDescription] AS [ShortDescription],
[Limit1].[LongDescription] AS [LongDescription],
[Limit1].[DisplayName] AS [DisplayName],
[Limit1].[ModuleItem_Id] AS [ModuleItem_Id]
FROM ( SELECT TOP (1)
[Extent1].[Id] AS [Id],
[Extent1].[Name] AS [Name],
[Extent1].[ShortDescription] AS [ShortDescription],
[Extent1].[LongDescription] AS [LongDescription],
[Extent1].[DisplayName] AS [DisplayName],
[Extent1].[ModuleItem_Id] AS [ModuleItem_Id]
FROM [dbo].[ItemControllers] AS [Extent1]
WHERE (([Extent1].[Name] = @p__linq__0) AND ( NOT ([Extent1].[Name] IS NULL OR @p__linq__0 IS NULL))) OR (([Extent1].[Name] IS NULL) AND (@p__linq__0 IS NULL))
) AS [Limit1]',N'@p__linq__0 nvarchar(4000)',@p__linq__0=N'Acl'
请检查tsql为什么EF创建这么长的查询,我可以简单地获取结果
通过以下查询
SELECT TOP (1)
[Extent1].[Id] AS [Id],
[Extent1].[Name] AS [Name],
[Extent1].[ShortDescription] AS [ShortDescription],
[Extent1].[LongDescription] AS [LongDescription],
[Extent1].[DisplayName] AS [DisplayName],
[Extent1].[ModuleItem_Id] AS [ModuleItem_Id]
FROM [dbo].[ItemControllers] AS [Extent1]
WHERE Name=@name // few code removed for clarity
。所以我的问题是如何使用linq函数
来改进EF实体的查询生成答案 0 :(得分:4)
我认为如果你查看两个查询(你的和生成的查询)的查询计划,你会发现差别很小。 Linq实际上非常擅长生成高效的SQL,实际上它添加到查询中的成本几乎为零。
唯一要检查这个SQL的是Name列上有一个索引。
干杯 -
答案 1 :(得分:0)
我同意上面的答案,但有一种方法可以准确控制SQL运行的查询(如果你想这样做),并且它是通过映射存储过程(你想要运行的确切查询)作为功能导入在实体框架中。然后,就像执行实体类一样调用函数import!
当然,这是更多的工作,因为你必须编写SQL和存储过程,但你可以这样做,它确实运行你的确切的SQL!
顺便说一句,EF设计师实际上非常擅长为您的结果创建自定义的“_result”类。当您将sproc映射为函数导入时,可以执行此操作。您可以在设计器中预览返回集,然后单击“创建自定义类”按钮。
我实际上是通过sprocs完成我的大部分EF工作,因为我不喜欢所有实体的混乱而且我通常会返回非常复杂的类,这些类不一定是我物理存储数据的方式!
试一试,你可能会喜欢它。