我使用asp.net 4 c#和ef4。
我有这个代码,它应该编译一个查询并返回一个标量值(我使用匿名类型)。
我的代码没有明显的错误,但是因为这是我第一次编写编译查询,我想知道是否编写得很好,或者可以通过改进来提高性能。
var query = CompiledQuery.Compile((CmsConnectionStringEntityDataModel ctx)
=> from o in ctx.CmsOptions
where o.OptionId == 7
select new
{
Value = o.Value
});
uxHtmlHead.Text = query(context).FirstOrDefault().Value;// I print the result in a Label
SQL配置文件输出:
SELECT TOP (1)
[Extent1].[OptionId] AS [OptionId],
[Extent1].[Value] AS [Value]
FROM [dbo].[CmsOptions] AS [Extent1]
WHERE 7 = [Extent1].[OptionId]
非常感谢
Wouter建议后的结果(请大家再次进行双重检查):
static readonly Func<CmsConnectionStringEntityDataModel, int, string> compiledQueryHtmlHead =
CompiledQuery.Compile<CmsConnectionStringEntityDataModel, int, string>(
(ctx, id) => ctx.CmsOptions.FirstOrDefault(o => o.OptionId == id).Value);
using (var context = new CmsConnectionStringEntityDataModel())
{
int id = 7;
uxHtmlHead.Text = compiledQueryHtmlHead.Invoke(context, id);
}
结果SQL(我不明白为什么使用LEFT JOIN)
exec sp_executesql N'SELECT
[Project1].[Value] AS [Value]
FROM ( SELECT 1 AS X ) AS [SingleRowTable1]
LEFT OUTER JOIN (SELECT
[Extent1].[Value] AS [Value]
FROM [dbo].[CmsOptions] AS [Extent1]
WHERE [Extent1].[OptionId] = @p__linq__0 ) AS [Project1] ON 1 = 1',N'@p__linq__0 int',@p__linq__0=7
答案 0 :(得分:2)
你可以改进两件事。
首先,预编译查询绝对是一个好主意,但如果您查看代码,您会看到它每次都会预编译查询而不是一次。
您需要将预编译的查询移动到仅初始化一次的静态变量。
您需要注意的另一件事是,在预编译查询时,您不应再在执行查询之前修改查询。
您正在构建一个预编译查询,它将选择所有行,然后您说'firstordefault'将预编译查询更改为SELECT TOP(1),您将失去预编译的好处。您需要在预编译查询中移动FirstOrDefault部分并仅返回一个结果。
查看this文档。如果查看这些示例,您可以看到它们如何使用静态字段来保存已编译的查询以及它们如何指定返回值。