Что будет захвачено запросом linq C # Entity Framework - PullRequest
0 голосов
/ 11 июня 2019

При реализации шаблона спецификации я придумал этот код

public static class ItemSpecification
{
    static public Expression<Func<Item, bool>> TodayOnlySpecification { get; } = item => item.ImplementationDate == DateTime.Today;
}

Это выражение позже будет использоваться в фильтрах EF linq для построения запросов. У меня вопрос, какая дата на самом деле используется в запросе. Это дата, когда статический класс впервые инициализируется? Или дата, на которую ссылается TodayOnlySpecification?

Конкретный сценарий будет

  1. Мое приложение запускается сегодня, и я ссылаюсь TodayOnlySpecification в первый раз на запрос linq, оно должно использовать сегодняшнюю дату для возможного sql

  2. Мое приложение продолжало работать, и завтра я снова ссылаюсь на TodayOnlySpecification для другого запроса linq. Будет ли использоваться сегодняшняя дата в запросе или будет использоваться завтрашняя дата?

Редактировать 1:

Тестирование с DateTime.Now и DateTime.Today дает очень разные результаты

  1. DateTime.Now создает следующий SQL-запрос:

    select ... 
    from ...
    where [Extent1].[ImplementationDate] = (SysDateTime())
    
  2. DateTime.Today создает следующий запрос SQL:

    select ... 
    from ... 
    where [Extent1].[ImplementationDate] = @p__linq__0',N'@p__linq__0 datetime2(7)',@p__linq__0='2019-06-11 00:00:00'`
    

Это всего лишь предположение, тот факт, что linq to entity может переводить DateTime.Now в SysDateTime(), означает, что он не использует значение DateTime.Now для перевода. Вместо этого он использует метод для получения текущего времени при генерации SQL. Это также должно означать, что DateTime.Today фиксируется как метод, а не как значение.

Редактировать 2:

Тогда возникает другой вопрос: если EF иногда оценивает метод на стороне клиента (например, DateTime.Today), а иногда - на стороне сервера (например, DateTime.Now), который может иметь другой часовой пояс, как это можно сделать? определить точное поведение запросов EF?

1 Ответ

0 голосов
/ 11 июня 2019

То, что попадает в плен, это

Expression.Call(
    null, //Static call so no instance
    methodOf(DateTime.Now),
    new Type[0] //No generic arguments
);

Другими словами.Ничто не попадает в плен.

Я рекомендую вам использовать отладчик для проверки IQueryable<T>.Expression, чтобы посмотреть на дерево.

EDIT:

Чтобы ответить на ваш вопрос о том, как EntityFramework обрабатывает вышеприведенное выражение.Это не так.Обрабатывается поставщик EntityFramework.

В случае EntityFramework.SqlServer код, который обрабатывает это, находится здесь

SqlFunctionCallHandler.HandleCanonicalFunctionCurrentDateTime line

...