Извлечь только первую строку из таблицы в Entity Framework - PullRequest
5 голосов
/ 15 декабря 2011

Справочная информация:

Entity Framework 4 с SQL Server 2008

Проблема:

У меня есть таблица Order.В каждой строке есть столбец Timestamp.

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

Например, если у меня есть заказы

2008-01-12
2009-04-17
2009-09-24
2010-11-02
2010-12-01
2011-05-16

и я выберу дату 2010-07-22, я должен получить 2009-09-24 order,потому что это последний заказ до указанной даты.

var query = (from oData in db.OrderDatas
            where oData.Timestamp <= userTime
            orderby oData.Timestamp ascending
            select oData).Last();

Это наиболее близко к тому, что я пытаюсь.Однако я не уверен, как именно работает оператор Last при переводе в SQL, если он вообще переведен.

Вопрос:

Получит ли этот запрос все данные (ранее userTime), а затем возьмет последний элемент или будет переведен так, чтобы только один элементбудет возвращен из базы данных?Моя таблица может содержать очень большое количество строк (100000+), поэтому здесь важна производительность.

Кроме того, как можно получить самое близкое время в базе данных (не обязательно раньше)?В примере 2010-07-22 можно получить 2010-11-02, поскольку оно ближе к указанной дате, чем 2009-09-24.

Ответы [ 3 ]

13 голосов
/ 15 декабря 2011

В общем, если вас беспокоит поведение LINQ, вам следует проверить, что происходит с SQL.Если вы еще не поняли, как увидеть, как ваши LINQ-запросы превращаются в SQL, это должно быть следующим, что вы сделаете.t поддерживается LINQ to SQL , поэтому то же самое может быть верно для EF.К счастью, вместо этого легко использовать First():

var query = (from oData in db.OrderDatas
             where oData.Timestamp <= userTime
             orderby oData.Timestamp descending
             select oData).First();
1 голос
/ 15 декабря 2011

Попробуйте использовать:

var query = (from oData in db.OrderDatas
         where oData.Timestamp <= userTime
         orderby oData.Timestamp descending
         select oData).Take(1);

Это эквивалент TOP 1

1 голос
/ 15 декабря 2011

Вопрос:

Будет ли этот запрос получать все данные (ранее userTime), а затем принимать последний элемент, или он будет переведен так, чтобы только один элемент будет возвращен из базы данных? Мой стол может держать очень большой количество строк (100000+), поэтому производительность является проблемой здесь.

В этом случае, используя подход first (), запрос будет выполнен немедленно, и он будет оптимизирован таким образом, что он только получит 1 запись. Скорее всего, топ (1) выберите. Вам действительно нужно проверить созданный sql с помощью инструмента sql profilihg или используя журнал datacontext. Или вы можете использовать linqpad. linq-2-sql может привести к N + 1 запросам, если не используется надлежащим образом. Такое поведение вполне предсказуемо, но в начале вы действительно должны осознавать.

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