所以我正在对我的SQLServer数据库的不同方法进行一些分析.我做了vanilla TSQL,CompiledQuery和一个未编译的Linq语句.
正如预期的那样,性能按照相同的顺序进行,但是在分析后两者时我发现了一些好奇的东西.
CompiledQuery生成的SQL比普通旧语句生成的SQL要好得多.
本地SQLExpress数据库; table被称为'foreignTable',ColumnA是int,主键(索引); ColumnB是随机int.
FuncGetByPK = CompiledQuery.Compile((testingDatabaseEntities1 ft, int key) => (ft.foreignTable.Where(x => x.ColumnA == key).FirstOrDefault().ColumnB));
生成
SELECT [Project1].[ColumnB] AS [ColumnB] FROM ( SELECT cast(1 as bit) AS X ) AS [SingleRowTable1] LEFT OUTER JOIN (SELECT TOP (1) [Extent1].[ColumnB] AS [ColumnB] FROM [dbo].[foreignTable] AS [Extent1] WHERE [Extent1].[ColumnA] = @p__linq__1 ) AS [Project1] ON 1 = 1
对于生成的代码,这真的不是太可怕了.
但是当我做普通的Linq声明时:
entity.foreignTable.Where(x => x.ColumnA == searchForMe).FirstOrDefault().ColumnB
它产生:
SELECT [Limit1].[C1] AS [C1], [Limit1].[ColumnA] AS [ColumnA], [Limit1].[ColumnB] AS [ColumnB], [Limit1].[FKColumn] AS [FKColumn] FROM ( SELECT TOP (1) [Extent1].[ColumnA] AS [ColumnA], [Extent1].[ColumnB] AS [ColumnB], [Extent2].[FKColumn] AS [FKColumn], 1 AS [C1] FROM [dbo].[foreignTable] AS [Extent1] LEFT OUTER JOIN (SELECT [Table_2].[FKColumn] AS [FKColumn], [Table_2].[SomeText] AS [SomeText] FROM [dbo].[Table_2] AS [Table_2]) AS [Extent2] ON [Extent1].[ColumnA] = [Extent2].[FKColumn] WHERE [Extent1].[ColumnA] = @p__linq__7 ) AS [Limit1]
这只是蹩脚的.
所以我想问题是:是否有可能将常规Linq给予实体与CompiledQuery相同数量的SQL suckiness?
您要比较的查询不一样.第一个编译的查询返回一个属性而不返回任何其他属性 它永远不会返回任何不同.第二个返回一个您取消引用然后访问其属性的实体实例.当查询执行时,它无法知道您只想查看一个属性.
您可以从非编译查询中获取相同SQL的一种方法(未经测试)是投影到匿名类型:
var b = (from e in entity.foreignTable. where ColumnA == searchForMe select new { ColumnB = e.ColumnB }).FirstOrDefault().ColumnB;