LINQ-запрос не работает без .ToList () - PullRequest
1 голос
/ 12 октября 2010

Рассмотрим следующие запросы LINQ-to-NHibernate:

var q1 = from se in query.ToList<SomeEntity>()
  where
  prop1 == "abc"
  select se;

var q2 = from se in q1
  where 
  m1(se.prop2) == "def"
  select  se;

q2 не будет работать с ошибкой: «Метод m1 не реализован». Но если заменить q2 на следующий запрос, все пойдет нормально:

var q2 = from se in q1.ToList<SomeEntity>()
  where 
  m1(se.prop2) == "def"
  select  se;

Почему это происходит? Как я могу заставить работать первый запрос? Это происходит только для LINQ-to-NHibernate или во всех запросах LINQ?

Ответы [ 4 ]

3 голосов
/ 12 октября 2010

Поскольку поставщик LINQ не может преобразовать метод m1 в совместимый оператор SQL.

Вызывая ToList<SomeEntity>(), вы читаете все это в память, а затем используете LINQ to Objects для фильтрации (и поскольку в этом случае запрос не переводится в SQL, проблем с выполнением запроса не возникает).

К сожалению, нет простого способа заставить первый запрос работать. Если вам действительно нужно использовать m1 для фильтрации результатов, вам сначала нужно будет что-то прочитать в память.

Это не просто ограничение LINQ to nHibernate. Это произойдет в любой ситуации, когда поставщик LINQ использует деревья выражений для преобразования вашего кода в другой язык (в этом случае он пытается преобразовать ваш код C # в операторы SQL, что аналогично тому, как это делают LINQ to SQL и Entity Framework).

1 голос
/ 12 октября 2010

Я бы сказал, что ваш исходный запрос q2 переводится в дерево выражений, а затем, когда NHibernate пытается его проанализировать, он обнаруживает, что метод не является частью его реализации.Преобразование запроса в коллекцию сначала с помощью ToList () использует функциональность LINQ в List, которая может поддерживать метод m1.

1 голос
/ 12 октября 2010

Предположительно, метод m1 не имеет перевода на SQL (по крайней мере, поставщик NHibernate LINQ не может понять, как это сделать). Когда у вас нет ToList, NHibernate пытается выяснить, как преобразовать m1 в SQL. Когда вы делаете ToList, NHibernate больше не играет роли и его LINQ-to-Objects, которые могут обрабатывать запрос. Это относится к ORM, которые включают LINQ; LINQ-to-SQL и EF постигнут схожие судьбы.

0 голосов
/ 05 февраля 2014

Я не знаю NHibernate, но сработает ли это?

var q2 = q1.where (x => m1(x.prop2) == "def");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...