2010-03-02 4 views
0

Я хочу создать оператор Where в моем выражении Linq, но ударил немного камнем преткновения.Поиск строк в Linq to Entity Framework

Я хотел бы разделить строковое значение, а затем выполнить поиск с использованием каждого элемента массива в предложении Where.

В моем обычном выражении Sql я бы просто перебирал массив строк и создавал там предложение Where, либо передавал это хранимой процедуре, либо просто выполнял строку sql. Но я не уверен, как это сделать с Linq для Entity?

(From o In db.TableName Where o.Field LIKE Stringvalue Select o).ToList() 
+0

Можете ли вы показать, как вы это сделаете в SQL, просто чтобы уточнить свою позицию как повторное чтение вашего вопроса. Я не уверен, что мой ответ удовлетворяет вашему запросу. – Lazarus

+0

Вы пытаетесь найти значения, соответствующие каждому элементу массива (AND) или любому (OR)? – MarkJ

+0

Для моего SQL, если бы я просто написал строку и выполнил ее, я бы написал ... dim Sql as string = "select fields from table where" Для каждого s как строка в Stringvalue.split (",") Sql + = "fieldname like '%" & s & "%' или" end for удалить финальную строку 'или' из строки и запустить этот sql –

ответ

1

Как насчет

(from o in db.Tablename 
    where o.Field.Contains(Stringvalue) 
    select o).ToList(); 
0
var fcs = from c in Contacts 
      where c.FirstName.ToLower().StartsWith(e.value.ToLower()) 
      select c; 

Вы можете использовать любую строку функций, таких как содержит, StartsWith и т.д.

+0

Многие люди используют трюк ToLower(), но вы не знаете, t должен. StartsWith имеет перегрузку, в которой вы можете поставить StringComparison.InvariantCultureIgnoreCase – Zyphrax

0

EDIT: неверно истолкованы ваш вопрос, как насчет:

string filters = "a,b,c,d"; 
var result = from filter in filters.Split(',') 
      from record In db.TableName 
      where record.Field.Contains(filter) 
+0

Это сравнение равенства, а не операция 'LIKE'. –

+0

@Adam, вы правы, неверно истолковали вопрос :) – Zyphrax

+0

Это работает, когда текст, который я ищу, является точным, но не для частичных совпадений. Но спасибо за код, поскольку он пригодится по линии –

1

Чтобы сделать динамическое построение, лучше всего использовать дерево выражений. Дайте этому выстрел:

IQueryable<EntityType> query = db.Tablename; 
Expression<Func<EntityType, bool>> expression = null; 

foreach (string item in yourString.Split(",")) 
{ 
    string localItem = item; // so that we don't close over the loop variable 

    Expression<Func<EntityType, bool>> exp = x => x.FieldName.Contains(localItem); 

    if (expression == null) 
    { 
     expression = exp; 
    } 
    else 
    { 
     expression = Expression.Lambda<Func<int, bool>>(
      Expression.OrElse(expression.Body, 
      Expression.Invoke(exp,expression.Parameters.Cast<Expression>())), 
      expression.Parameters); 
    } 
} 

var results = query.Where(expression).ToList(); 
+0

Спасибо Adam Это работает, хотя и возвращает список, который соответствует последнему элементу в массиве строк. Итак, если строковое значение было «a, b, c, d», оно вернет только те, которые соответствуют «d». Есть ли способ присоединиться к запросу в цикле for так, чтобы конечный query.ToList() содержит query.where (x => x.fieldname.contains ("a")) и query.where (x => x .fieldname.contains ("b")) ....? –

+0

Вы можете использовать Union для объединения запросов вместе, как и мой ответ – MarkJ

+0

@Jim: Дайте это отредактировать снимок. Мой первоначальный ответ был неправильным в том смысле, что он был спроектирован как «И», когда вы действительно хотите, чтобы «OR» и «b» он закрывал переменную цикла (d'oh!), Поэтому он только совпадал последнее условие. –

0

воздуха код здание на ответ Адама и используя Union приковать результаты вместе, подражая И вместо ИЛИ.

EDIT Я удалил свою рекомендацию использовать Distinct, потому что Union отфильтровывает дубликаты.

var query = null; 

foreach(string item in yourString.Split(",")) 
{ 
    var newquery = db.Tablename.Where(x => x.FieldName.Contains(item)); 
    if (query == null) { 
     query = query.union(newquery);  
    } else { 
     query = newquery; 
    } 
} 

var results = query.ToList(); 
+0

Хмм, это не работает для меня. Я получаю сообщение об ошибке: InnerException = {"Тип текстовых данных не может быть выбран как DISTINCT, потому что он не сопоставим. Тип текстовых данных не может быть выбран как DISTINCT, потому что он не сопоставим."} –

+0

Я думаю, это означает, что типы не реализуйте IComparable? Правильно ли это звучит? – MarkJ

+0

На самом деле я ошибся: вам не нужно использовать Distinct, Union уже отфильтровывает дубликаты – MarkJ

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