Может ли LINQ to SQL IQueryable быть неожиданно оценен? - PullRequest
1 голос
/ 06 февраля 2011

Я пишу некоторый код, который принимает LINQ to SQL IQueryable<T> и добавляет дополнительные динамически генерируемые предложения Where.Например, вот скелет одного из методов:

IQueryable<T> ApplyContains(IQueryable<T> source, string field, string value)
{
   Expression<Func<T, bool>> lambda;
   ... dynamically generate lambda for p => p.<field>.Contains(value) ...
   return source.Where(lambda);
}

Я мог бы соединить несколько из этих методов вместе и закончить со страницей Skip / Take.

Правильно ли я думаючто, когда IQueryable окончательно вычисляется, если в лямбда-выражениях есть что-то, что не может быть переведено в SQL, будет выдано исключение?В частности, я обеспокоен тем, что мог бы случайно сделать что-то, что заставило бы IQueryable оценивать рано и затем продолжить оценку в памяти (тем самым извлекая тысячи записей).Я подозреваю, что IQueryable не оценит так рано.Кто-нибудь может подтвердить это, пожалуйста?

Ответы [ 2 ]

3 голосов
/ 06 февраля 2011

Да, вы правы, полагая, что ваш IQueryable может выдать ошибку во время выполнения, если часть выражения не может быть переведена в SQL.Из-за этого я думаю, что было бы неплохо иметь ваши запросы в классе бизнес-уровня (например, в службе данных или хранилище), а затем убедиться, что этот запрос покрыт автоматическим тестом.в неожиданное время основное правило, которое нужно иметь в виду, это то, что ваше выражение будет оцениваться всякий раз, когда вы вызываете foreach для него.Это также включает методы, которые вызывают foreach за кулисами, например ToList() и FirstOrDefault().

Кстати, простой способ определить, будет ли метод вызывать foreach и заставлять вашу лямбду вычислять, - это проверить, является ли возвращаемое значение этого метода IQueryable.Если возвращаемое значение является другим IQueryable, то метод, вероятно, просто добавляет к выражению, но не заставляет его оценивать.Если возвращаемое значение является List<T>, анонимным типом или чем-то, что выглядит как данные вместо IQueryable, тогда метод должен был заставить ваше выражение выполнить оценку для получения этих данных.

2 голосов
/ 06 февраля 2011

Ваше мышление правильно.

Пока вы передаете IQueryable an Expression в предложениях Where, оно не будет оцениваться неожиданно.

Кроме того, методы расширения, начинающиеся с "To", будут вызывать оценку (т.е.ToList (), ToArray ()).

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