C # поиск с использованием запроса LINQ с дочерними записями - PullRequest
0 голосов
/ 25 января 2019

У меня есть объект Person и PersonType, где у Person есть один-много PersonTypes.PersonType может быть бухгалтером, консультантом и т. Д.

Таблица Person имеет следующие столбцы: 'имя' |'фамилия' |«электронная почта» |'phonenumber'

Таблица PersonType имеет следующие столбцы: 'name' |'description'

Я создал механизм поиска с использованием LINQ в C #, но проблема в том, что я получаю неправильный результат из-за проблемы с ограничением LINQ.Предположим, у нас есть две записи Person, где первая запись - это «Консультант», а другая запись - «Консультант и бухгалтер», что означает, что она имеет отношение к дочерним объектам.

Примечание.Мой поиск нечувствителен к регистру.

Предположим, мой текст поиска - 'co'.Тогда я не хочу, чтобы результат был 3 записи.Теперь он возвращает первое лицо и два экземпляра второго лица из-за двух совпадений 'co' для бухгалтера и консультанта для второго лица.

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

Большое спасибо за ваш вклад.

ВотLinq:

private IList<PersonViewModel> SearchAll(string searchCriteria)
{
   var result = System.Web.HttpContext.Current.Session["Persons"] as IList<PersonViewModel>;

    if (result != null)
    {
        var v = (from a in result
                 from b in a.PersonTypes
                    where
                            a.FirstName.CaseInsensitiveContains(searchCriteria) ||
                            a.LastName.CaseInsensitiveContains(searchCriteria) ||
                            a.Email.CaseInsensitiveContains(searchCriteria) ||
                            a.PhoneNumber.CaseInsensitiveContains(searchCriteria) ||
                            b.Name.CaseInsensitiveContains(searchCriteria)
                 select a);

        return v.ToList();
    }

    return result;
}

Ответы [ 3 ]

0 голосов
/ 26 января 2019

Вы можете получить результат следующим образом

var v=result?.Where(p=>p.PersonTypes.Select(t=>t.Name).Contains(searchCriteria)    ||
                            p.FirstName.CaseInsensitiveContains(searchCriteria)   ||
                            p.LastName.CaseInsensitiveContains(searchCriteria)    ||
                            p.Email.CaseInsensitiveContains(searchCriteria)       ||
                            p.PhoneNumber.CaseInsensitiveContains(searchCriteria) ||)?.ToList();
0 голосов
/ 26 января 2019

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

Запрашивать только те объекты, которые вам нужны, и ничего не делать, кроме where.

Вам нужно PersonViewModel с.Присоединяясь к PersonTypes (from - from является GroupJoin), также PersonTypes становятся доступными для конечного результата.Поэтому, если вы запрашиваете только те сущности, которые вам нужны, должен быть один и только один, from:

var v = from a in result

Теперь, каким должен быть where?Условия для PersonViewModel ясны, но как насчет PersonTypes?Слабое определение на простом языке, , где хотя бы один из их PersonTypes содержит "co" .В LINQ это составляет:

var v = from a in result
    where a.FirstName.CaseInsensitiveContains(searchCriteria)
       || a.LastName.CaseInsensitiveContains(searchCriteria)
       || a.Email.CaseInsensitiveContains(searchCriteria)
       || a.PhoneNumber.CaseInsensitiveContains(searchCriteria)
       || a.PersonTypes.Any(pt => pt.Name.CaseInsensitiveContains(searchCriteria));

Теперь вам не нужно Distinct, потому что нет join, который дублирует результаты.

0 голосов
/ 25 января 2019

Салам, я думаю, вы можете сделать это так

v.GroupBy(person => person.id)
  .Select(g => g.First())
  .ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...