2013-11-13 3 views
2

Мне нужно использовать операторы LIKE в динамическом WHERE.Linq to sql, используя как в динамике, где статья

настоящее время я использую = операторов, но необходимо заменить LIKE:

String whereClause = "1 = 1 AND "; 
whereClause = whereClause + (search.Id != null ? "Id = " + search.Id + " AND " : ""); 
whereClause = whereClause + (search.FirstName != null ? "FirstName = \"" + search.FirstName + "\" AND " : ""); 
whereClause = whereClause + (search.LastName != null ? "LastName = \"" + search.LastName + "\" AND " : ""); 
whereClause = whereClause + (search.StudentName != null ? "StudentName = \"" + search.StudentName + "\" AND " : ""); 
whereClause = whereClause + (search.Country != null ? "CountryLabel = \"" + search.Country + "\" AND " : ""); 
whereClause = whereClause + (search.ZipCode != null ? "ZipCode = \"" + search.ZipCode + "\" AND " : ""); 
whereClause = whereClause + (search.City != null ? "City = \"" + search.City + "\" AND " : ""); 
whereClause = whereClause.Remove(whereClause.Length - 5); 

IEnumerable<MyClassDto> res = (
    from ... 
    where ... 
    select new MyClassDto() { 
     ... 
    } 
).Where(whereClause); 
  1. Я не могу использовать Contains(), StartsWith() или EndsWith() как параметры поиска могут быть в виде «% моего% стоимости».
  2. Я не могу использовать SqlMethods.Like() в динамическом WHERE статье.
  3. Я не хочу включать его в предложение WHERE запроса MyClassDto, поскольку он замедляет время выполнения, поэтому я применяю другое предложение WHERE на Enumerable, сопоставляя только параметры поиска.

Любые предложения?

+1

В таких ситуациях я предпочитаю использовать старое пространство имен 'SqlClient', и сами заполнить модели. –

+0

Я, наконец, использовал необработанный SQL-запрос с использованием 'myDb.Database.SqlQuery()', не оптимальный для обслуживания, но, по-видимому, является самым простым и быстрым решением, позволяющим использовать оператор 'LIKE'. – Yann39

ответ

2

Я бы использовал PredicateBuilder.

Пожалуйста, смотрите здесь: http://www.albahari.com/nutshell/predicatebuilder.aspx

+0

Я не смог использовать это решение с 'SqlMethods.Like()' – Yann39

+0

Пожалуйста, смотрите этот вопрос, как использовать аналогичный оператор. http://stackoverflow.com/questions/835790/how-to-do-sql-like-in-linq – hutchonoid

+0

Принятый ответ рекомендует использовать 'Contains()' для замены 'LIKE' оператора? Я очень удивлен, что этот ответ получил 217 upvotes ... Также 'SqlMethods.Like()' доступен только в Linq to SQL, а не в Linq для сущностей. И я не могу построить динамическое предложение where, использующее Linq to SQL. Но используя указанную ссылку, я наткнулся на этот сайт, который, кажется, предлагает решение: http://jendaperl.blogspot.ch/2011/02/like-in-linq-to-entities.html – Yann39

0

Это может быть не так элегантно, как PredicateBuilde упоминалось в другом ответе, но он должен получить работу.
Вы можете предоставить метод как предложение where, например:
Редактировать: Заменить == любым другим оператором сравнения, если необходимо.

public bool WhereClause(MyClassDto s, SearchClass search) 
{ 
    if ((s.Id == null || s.Id == search.Id) && 
     (s.FirstName == null || s.FirstName == search.FirstName) && 
     (s.LastName == null || s.LastName == search.LastName) && 
     (s.StudentName == null || s.StudentName == search.StudentName) && 
     (s.Country == null || s.Country == search.Country) && 
     (s.ZipCode == null || s.ZipCode == search.ZipCode) && 
     (s.City == null || s.City == search.City)) 
    { 
     return true; 
    } 
     return false; 
} 

Использование:

IEnumerable<MyClassDto> res = (
    from ... 
    where ... 
    select new MyClassDto() { 
     ... 
    } 
).Where(my => WhereClause(my, search)); 

Альтернативное решение:

Создать список методов и передать их в тех случаях, когда:

var whereClause = new List<Func<MyClassDto, SearchClass, bool>>(); 
if (search.Id != null) whereClause.Add((s, dto) => s.Id == dto.Id); 
if (search.FirstName != null) whereClause.Add((s, dto) => s.FirstName == dto.FirstName); 
if (search.LastName != null) whereClause.Add((s, dto) => s.LastName == dto.LastName); 
if (search.StudentName != null) whereClause.Add((s, dto) => s.StudentName == dto.StudentName); 
if (search.Country != null) whereClause.Add((s, dto) => s.Country == dto.Country); 
if (search.ZipCode != null) whereClause.Add((s, dto) => s.ZipCode == dto.ZipCode); 
if (search.City != null) whereClause.Add((s, dto) => s.City == dto.City); 

IEnumerable<MyClassDto> res = (
    from ... 
    where ... 
    select new MyClassDto() { 
     ... 
    } 
).Where(dto => whereClause.All(func => func(dto, search))); 
+0

Ваше решение работает, но Цель заключалась в том, чтобы избежать указания параметров поиска в предложении 'WHERE', если они не указаны по соображениям производительности. Даже если все параметры равны нулю, запрос будет очень медленным, чем если бы вы их не указали. – Yann39

+0

@ Yann39 Я предложил другое решение. – Kabbalah

+0

Фокус в том, что, похоже, нет возможности использовать 'LIKE' в Linq для Entities, он разрешен только в Linq to SQL. Таким образом, ваше решение будет работать с использованием '==' оператора, но не с помощью 'SqlMethods.Like()'. – Yann39

Смежные вопросы