2016-01-26 3 views
0

У меня есть Linq заявление в качестве такогозаявляющие какие условия были согласованы в LINQ, где

dbContext.Items 
.Where(
p => 

    (p.Client.Contact != null && p.Client.Contact.Firstname.ToLower().Contains(searchText.ToLower())) 
    || 
    (p.Client.Contact != null && p.Client.Contact.Surname.ToLower().Contains(searchText.ToLower())) 
    || 
    (p.PolicyNumber != null && p.PolicyNumber.ToLower().Contains(searchText.ToLower())) 
    || 
    (
    p.PolicyLivesAssureds 
    .Where(
     pl => 
     pl.Contact != null && pl.Contact.Firstname.ToLower().Contains(searchText.ToLower()) 
     || pl.Contact.Surname.ToLower().Contains(searchText.ToLower()) 
     ).Count() > 0 
) 
) 
).OrderBy(p => p.IeUtem); 

Это действительно необходимо в автозаполнения. То, что я хочу сделать, - это точно знать, какой из моих 5 условий был сопоставлен, и отобразить конкретный элемент, который был сопоставлен. Например, скажем, что PolicyNumber был сопоставлен, я хочу отправить только номер полиса для этой строки, а для других, если имя было сопоставлено, я хочу отправить только имя для этой строки.

Есть ли способ сделать это;

+0

Так как вы используете 'OR' я рекомендовал бы разбить его в 5 отдельные запросы. Таким образом, легче подсчитывать результаты отдельных компонентов и сохранять их в выделенном объекте. Хотя, поскольку вы используете 'OrderBy', вы можете захотеть снова объединить данные. – Stefan

+0

Вы используете C# 6.0? Это вы так, некоторое выражение можно упростить, например: 'p.Client.Contact! = Null && p.Client.Contact.Firstname.ToLower(). Содержит (searchText.ToLower())' to 'p.Client.Contact? .Firstname.ToLower(). Содержит (SearchText.ToLower()) ' – Ian

ответ

0

Вопрос будет, как вы хотите узнать, какие запросы совпадают. Например, вы могли бы сделать что-то вроде этого

class AutoCompleteItem { 
    String Text {get; set;} 
    Item Item {get; set;} 
} 

var firstNames = dbContext.Items.Select(p => new AutoCompleteItem { Name = p.Client.Contract.FirstName, Item = p}) 

var lastNames = dbContext.Items.Select(p => new AutoCompleteItem { Name = p.Client.Contract.SurName, Item = p}) 

var result = firstName.Union(lastNames).Where(p => p.Name.Contains(searchText)).OrderBy(a => a.Item.IeUtem); 

Теперь AutcompleteItem это класс, который содержит текст, который вы хотите (и, возможно, какие-либо другие поля, которые необходимо, как информация, какое поле было то, что соответствует)

Идея здесь находится MVVM patttern. У вас есть модель (элементы). Теперь вам нужно создать viewModel (AutoCompleteItems), который реально помогает вам отображать то, что вы хотите.

+0

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

+0

Linq выполнит ваш запрос только при фактическом использовании результатов. Поэтому, когда вы делаете окончательный список ToList, он должен выполнить весь запрос. – Batavia

0

Это немного больше пищи для размышлений ответа, как это имеет недостатки в его подход, но я думаю, что это не решает проблему:

double[] items = { 1, 2, 3, 4, 5 }; 
IEnumerable<Tuple<double, int>> results = items.Select(x => 
    { 
     int index = 0; 
     foreach (var condition in new Func<bool>[] 
      { 
       // TODO: Write conditions here. 
       () => x == 1, 
       () => x == 2 
      }) 
     { 
      if (condition() == true) 
       return index; 
      else 
       index++; 
     } 
     return -1; 
    }).Zip(items, (matchedCondtion, item) => Tuple.Create(item, matchedCondtion)) 
    .Where(x => x.Item2 != -1); 

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

Первый выбор возвращает целое число для каждого элемента коллекции. Если существует совпадение условий, оно возвращает индекс условия. Если нет совпадения, он возвращает -1.

Он делает это путем перечисления коллекции Func и возврата индекса первого истинного условия (эмулируя короткое замыкание оператора ||). Если никакие условия не совпадают, это просто возвращает -1 после оценки всех условий.

Эти результаты затем заархивированы с помощью оригинальной коллекции (с использованием набора), сопоставляя каждый элемент с индексом его условия соответствия (или -1).

Так пример возвратит:

{ 1, 0 }, 
{ 2, 1 }, 
{ 3, -1 }, 
{ 4, -1 }, 
{ 5, -1 } 

Этот результат затем просто отфильтрованную с помощью Where для удаления записей с -1, оставив вас с коллекцией элементов, соответствующих условию, а индекс состояния который соответствует (в виде кортежа).

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

// TODO: Write conditions here. 
Смежные вопросы