EF Pre Compile query and return of a scalar value

元气小坏坏 提交于 2019-12-12 01:49:39

问题


I use asp.net 4 c# and ef4.

I have this code, it should compile a query and return a single scalar value (I use anonymous type).

My code does not have apparently errors, but because is the first time I write a compiled query I would like to know if is well written or could be improved for a performance boost.

   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 Profile Output:

SELECT TOP (1) 
[Extent1].[OptionId] AS [OptionId], 
[Extent1].[Value] AS [Value]
FROM [dbo].[CmsOptions] AS [Extent1]
WHERE 7 = [Extent1].[OptionId]

Many Thanks


Result after Wouter advice (please guys have a double check again):

        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);
            }

Resulting SQL (I do not understand why with a 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

回答1:


There are 2 things you can improve on.

First, precompiling a query is definitely a good idea but if you have a look at your code you will see that it precompiles the query each and every time instead of only once.

You need to move the precompiled query to a static variable that is initialized only once.

Another thing you need to be careful of is that when precompiling a query you shouldn't modify the query anymore before executing it.

You are building a precompiled query that will select all rows and then you say 'firstordefault' which changes the precompiled query to a SELECT TOP (1) and you lose the benefit of precompiling. You need to move the FirstOrDefault part inside your precompiled query and return only one result.

Have a look at this documentation. If you look at the examples you can see how they use a static field to hold the compiled query and how they specify the return value.



来源:https://stackoverflow.com/questions/8267331/ef-pre-compile-query-and-return-of-a-scalar-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!