Entity Framework и различия между Contains между SQL и объектами, использующими ToLower - PullRequest
0 голосов
/ 08 июня 2010

Я столкнулся с «проблемой», я не совсем уверен, что понимаю с Entity Framework.Я использую Entity Framework 4 и пытался использовать подход TDD.В результате я недавно реализовал функцию поиска, используя шаблон Repository.Для моего тестового проекта я реализую свой интерфейс репозитория и у меня есть набор «поддельных» данных объекта, которые я использую для целей тестирования.

Я столкнулся с проблемой, пытаясь заставить предложение Contains работать для инварианта регистрапоиск.Мой фрагмент кода для моего теста и класса репозитория, используемого для базы данных, выглядит следующим образом:

if (!string.IsNullOrEmpty(Description))
{
     items = items.Where(r => r.Description.ToLower().Contains(Description.ToLower()));
}

Однако, когда я запускал свои тестовые случаи, результаты не заполнялись, если мой случай не соответствовал базовым данным,Я некоторое время пытался разобраться в том, что считал проблемой.Чтобы очистить свой разум, я попытался и подумал, будет ли тот же код с EF работать с внутренней базой данных SQL, поскольку SQL явно поддерживает команду like и выполняется так, как я ожидал, с использованием той же логики.

Я понимаю, почему EF для базы данных поддерживает предложение Contains.Тем не менее, я был удивлен, что мои юнит-тесты не сделали.Любые идеи, почему кроме поддержки SQL-сервером предложения like, когда я использую объекты, которые я заполняю в коллекции, а не на сервере базы данных?

Спасибо!

Джон

1 Ответ

4 голосов
/ 08 июня 2010

LINQ to Entities и LINQ to Objects имеют разные правила. Это так просто. Например, в LINQ to Entities я могу выполнить запрос, подобный этому:

var foo = Context.Foos.Where(f => f.Bar.Something == bar);

... И если f.Bar окажется пустой ссылкой, этот оператор будет работать нормально, потому что f.Bar.Something слится в null. Если вы думаете о том, как работает SQL с левым соединением, это не должно удивлять. В LINQ для объектов, с другой стороны, то же самое выражение Where выдает исключение нулевой ссылки.

Как вы обнаружили, есть и другие отличия. Чувствительность к регистру одна. Когда выполняется запрос LINQ to Entities, он преобразуется в SQL. Сравнения равенства выполняются на основе правил сопоставления, определенных в базе данных, а также в SQL. Чтобы настроить параметры сортировки для базы данных, вы обычно выбираете конкретный параметр сортировки для столбца. С другой стороны, для настройки параметров сортировки для объектов вы обычно передаете функцию сравнения, которая никогда не будет принята в LINQ to Entities, поскольку функции (в отличие от выражений) не могут быть преобразованы в SQL.

Однако существует способ сравнения без учета регистра, который работает в обоих поставщиках LINQ:

var foo = Context.Foos.Where(f => f.SomeString.Equals(someValue, StringComparison.OrdinalIgnoreCase));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...