int[] ids1 = { 1, 2, 3 };
int[] ids2 = { 1, 5, 6 };
var result = from a in ids1
where a == ids2.First()
select a;
foreach (var item in result) ; //ok
var employees = from c in context.Employees.
where c.EmployeeID == ids1.First()
select c;
foreach (var item in employees); // NotSupportedException
При попытке вызвать ids1.First
в запросе Linq-to-Entities я получаю исключение System.NotSupportedException: метод «Первый» может использоваться только как конечная операция запроса.Попробуйте использовать метод FirstOrDefault в этом случае вместо .
a) Я не понимаю, почему First
можно использовать только как окончательную операцию запроса, поскольку в нашем примере First
вызывается на IEnumerable<>
(ids1.First()
), а не на IQueryable<>
.Другими словами, First
вызывается в запросе Linq-to-Objects, а не в запросе Linq-to-Entities ?!
b) В любом случае, почему First
должна использоваться в качестве конечной операции запроса, в то время как FirstOrDefault
не должна быть конечной операцией запроса?
Спасибо
ОТВЕТИТЬ:
Что касается разницы между First () и FirstOrDefault () - я не знаю.Вы пробовали, и это работает?
Да, это работает
Нет, First () вызывается в запросе LINQ to Entities.Ваше предложение where будет преобразовано в: Где (c => c.EmployeeID == ids1.First ())
a) Теперь я немного растерялся.Я понимаю, что ids1.First
по существу вызывается в запросе Linq-to-Entities, но факт остается фактом: First
вызывается в IEnumerable<>
, и, как таковой, First
вызывается в запросе Linq-to-Objects, и этот Linqзапрос to-Object в свою очередь вызывается в запросе Linq-To-entity - по крайней мере, я так понимаю ?!
Или вы подразумеваете, что First
как-то вызывается IQeryable<>
?
b) Я понимаю, что (c => c.EmployeeID == ids1.First())
будет преобразовано в дерево выражений, но почему нет ids1.First()
выполнено до преобразования?
c) В любом случае, когда преобразование в дерево выражений произойдет, я предполагаю, что когда поставщик sql получает дерево выражений нашего предложения where
и пытается преобразовать его в команду Sql, этот поставщик Sql не имеет«сила» для выполнения ids1.First
, чтобы получить результат обратно (который он затем поместил бы в Sql-запрос), и, следовательно, исключение?!
ВТОРОЙ ОТВЕТ:
a) Я все еще не понимаю, почему ids1.First
не выполняется до преобразования дерева выражений ?!А именно, в следующем предложении
Where(c => c.EmployeeID == 2+3)
выражение 2+3
выполняется до того, как это предложение Где преобразуется в дерево выражений!И ids.First
также является своего рода выражением, поэтому я ожидал бы похожего поведения?!
b) Извините за повторение, но меня действительно беспокоит, вызвано ли мое предположение - что First
вызывается в Linqзапрос to-Objects, и этот запрос Linq-to-Object, в свою очередь, вызывается в запросе Linq-To-entity - это правильно?!
c) Возможно, я неправильно понял Ваш пост, но вы подразумеваете, что большинство другихОператоры Linq-to-Object можно вызывать для IEnumerable<> E
, даже если в запросе Linq-to-Entities содержится E
?