EF Pre Compile запрос и возврат скалярного значения - PullRequest
0 голосов
/ 25 ноября 2011

Я использую 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

1 Ответ

2 голосов
/ 25 ноября 2011

Есть две вещи, которые вы можете улучшить.

Во-первых, предварительная компиляция запроса, безусловно, хорошая идея, но если вы посмотрите на свой код, вы увидите, что вместо этого он прекомпилирует запрос каждый раз.только один раз.

Вам нужно переместить предварительно скомпилированный запрос в статическую переменную, которая инициализируется только один раз.

Еще одна вещь, с которой вам следует быть осторожным, это то, что при предварительной компиляции запроса вы не должны 't больше не изменяйте запрос перед его выполнением.

Вы создаете предварительно скомпилированный запрос, который выберет все строки, а затем вы говорите «firstordefault», который заменяет предварительно скомпилированный запрос на SELECT TOP (1), и вы теряете преимуществопрекомпиляции.Вам нужно переместить часть FirstOrDefault внутри предварительно скомпилированного запроса и вернуть только один результат.

Просмотрите эту документацию.Если вы посмотрите на примеры, вы увидите, как они используют статическое поле для хранения скомпилированного запроса и как они указывают возвращаемое значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...