LINQ «Где» не работает - PullRequest
       3

LINQ «Где» не работает

2 голосов
/ 02 ноября 2011

Я немного запутался, почему этот фрагмент кода создает 2 записи в списке (действует правильно):

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 действовать неправильно.

Ответы [ 3 ]

1 голос
/ 02 ноября 2011

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

1 голос
/ 02 ноября 2011

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

 var historiesToRemove = this.WorkHistories.Where( h => h.Tool.ID == tool.ID )
                                           .ToList();
1 голос
/ 02 ноября 2011

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


Читайте о замыканиях и 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...