2012-04-05 2 views
0

Итак, у меня есть это предложение запроса linq.LINQ Запрос для имитации IS IN

var ctx = new Context(); 
IQueryable<Users> consulta = ctx.Users; 

if (filters.Count > 0) 
    query = query.Where(p => filters.Contains(p.Name) || 
          filters.Contains(p.LastName)); 

Фильтры

Является список строк, содержащий неупорядоченные имена и lastnames (не обязательно полное). Например: Filter {Mary, Joseph Ken}, но DB {Mary Katie, Joseph Kendall}.

Ожидаемые результаты

Для предыдущих фильтров я хочу запрос, чтобы вернуть список пользователей, независимо от того, если в фильтрах его названия и lastnames являются неполными, но правильно. Поэтому, если у фильтра есть «Мэри», он должен найти запись db с «Mary Katie» и так далее.

+6

Ваш вопрос не заполнен. Попытайтесь понять свой собственный вопрос, не зная никаких подробностей. Что такое 'запрос' и' фильтры'? Предоставьте образцы данных и желаемый результат. –

+0

Если это тег linq2entity, это соответственно. –

+0

@SaeedAmiri - это код сущности. –

ответ

2

Вы можете использовать сочетание String.Contains и Any, чтобы решить вашу проблему в linq2entity без извлечения дополнительных данных из БД:

var ctx = new Context(); 
IQueryable<Users> consulta = ctx.Users; 

if (filters.Count > 0) 
    query = query.Where(p => filters.Any(x=>x.Contains(p.Name)) || 
          filters.Any(x=>x.Contains(p.LastName)) || 
          filters.Any(x=>p.Name.Contains(x)) || 
          filters.Any(x=>p.LastName.Contains(x))); 
+0

Кажется, что не работает. Набор результатов повторен. Только нашел пользователей с именем say «Bob Knob», если фильтр «Bob Knob» не «Bob». –

+0

OK Я отредактирую его. –

+0

@ RandolfRincón-Fadul, см. Мое редактирование, это должно сработать для вас, вы можете удалить дополнительные вызовы 'Any', на самом деле я не знаю ваш точный формат БД и фильтра, и я написал все возможные случаи. Но это не оказывает существенного влияния на производительность. –

3

Я думаю, что вы хотите дан фильтр

Bob 
Alice 
Jane 

и элементы в запросе, такие как

Bob Nob 
Alice Howzer 
Jane Bob 
Tim 

вы получите

Bob Nob 
Alice Howzer 
Jane Bob 

Поскольку фильтр соответствует какой-либо части от первого или последнего имени?

Почему бы не добавить метод расширения в вашей коллекции, что делает что-то вроде

public static bool IsInAny(this IEnumerable<String> source, string name, string delim = " ") 
{ 
    return source.Any(item => 
          { 
          var splits = name.Split(new[] { delim }, StringSplitOptions.RemoveEmptyEntries); 
          return splits.Contains(item); 
          }); 
} 

Вот это тест, который вы можете использовать, чтобы проверить его

[Test] 
public void TestInAny() 
{ 
    var filters = new[] {"Bob", "Alice"}; 
    var items = new[] {"Bob Knob", "Alice Jane", "Tim"}; 

    var found = items.Where(i => filters.IsInAny(i)).ToList(); 
} 

Очевидно, что это просто быстрый и грязный способ и есть более чистые способы сделать это, но по крайней мере теперь вы инкапсулировали логику.

+1

Это не будет работать в linq2entity, и, похоже, OP работает с linq2entity. –

+0

Devshorts, спасибо за вашу помощь, но кажется @SaeedAmiri прав. LINQ to Entities не распознает метод 'Boolean IsInAny (System.Collections.Generic.IEnumerable'1 [System.String], System.String, System.String)' метода. –

0

Может быть что-то вдоль этих линий? Я на самом деле не проверял его, поэтому покупатель остерегался.

public static bool IsIn(this string value, IEnumerable<string> compareList) 
{ 
    foreach (string compareValue in compareList) 
    { 
     if (value.Contains(compareValue)) 
       return true; 
    } 
     return false; 
} 
+0

Это плохой способ в linq2entity, на самом деле вы должны получить все данные, и это дьявол. –

+1

Не заметил, что это было в контексте LinqToEntity. Виноват. Метод расширения должен быть переводимым в инструкцию SQL. – richk

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