2011-11-02 3 views
2

Я немного запутался, почему этот кусок кода производит 2 записей в виде списка (акты соответственно):LINQ «Где» Заявление не работает

var historiesToRemove = new List<WorkHistory>(); 
       foreach (var history in this.WorkHistories) 
       { 
        if (history.Tool.Equals(item)) 
        { 
         historiesToRemove.Add(history); 
        } 
       } 

В то время как этот кусок кода создает пустой список :

var historiesToRemove = this.WorkHistories.Where(history => history.Tool.Equals(item)).ToList(); 

Любые идеи, почему это может случиться?

ПРИЧИНА:

я не правильно реализовать IQueryable свойства IDbSet в. Это сделало мой LINQ действительным.

+0

Рабочие места IDbSet ? – ChrisBD

+0

Да. Проблема решена, прочитайте комментарии принятого ответа. – Martynas

+0

Ответ, который вы приняли, был удален модератором (возможно, из-за низкого качества). На мой взгляд, ответы Бен Робинсона и тванфоссона верны. Выбор (новый) - ваш :) – Slauma

ответ

1

IDbSet, что вы упоминаете в комментариях является частью структуры объекта, так что ваши 2 части кода не эквивалентны. LINQ - это дерево выражений, которое преобразуется в SQL с помощью EF, тогда как первый бит кода возвращает всю таблицу из базы данных и выполняет цикл в памяти. Профилируйте базу данных, чтобы узнать, что SQL выполняет в базе данных, и это должно дать вам представление о том, почему linq не делает то, что вы хотите.

1

Редактировать: Только что у вас есть ToList в конце запроса, поэтому нижеприведенное не применяется.


Читайте также: closures and LINQ. Вероятно, «элемент» изменяется перед запуском запроса.

Пример Код ошибки:

var filter = "Compare"; 

var query = from m in typeof(String).GetMethods() 
      where m.Name.Contains(filter) 
      select new { m.Name, ParameterCount = m.GetParameters().Length }; 

filter = "IndexOf"; 

foreach (var item in query) 
    Console.WriteLine(item); 
+1

Я не уверен, что это так, потому что 'ToList()' вызывает выполнение лямбда. – HuBeZa

+0

Прочитайте первую строку в моем ответе. Отредактировано некоторое время назад. –

1

Это всего лишь предположение, но я бы сказал, что вы, вероятно, предоставили определение равенства, отличное от определения, используемого в LINQ-переводе в EF. В EF я считаю, что он использует равенство свойств, тогда как вы можете проверить только то, что идентификаторы одинаковы. Я предлагаю вам явно кодировать определение равенства, которое вы хотите проверить в своей инструкции LINQ. Причина, по которой ваше определение равенства работает в первом случае, заключается в том, что перечисление IDbSet приводит его в память и, таким образом, вызывает вашу версию Equals, а не LINQ-to-EF перевод Equals.

var historiesToRemove = this.WorkHistories.Where(h => h.Tool.ID == tool.ID) 
              .ToList(); 
Смежные вопросы