В Linq для Entity Framework, какова наилучшая практика для возврата результирующего набора путем запроса нескольких столбцов для строки поиска?

#c# #entity-framework #linq

#c# #entity-framework #linq

Вопрос:

Я пишу общий поисковый запрос внутри репозитория EF5, который будет искать в нескольких столбцах определенную строку.

В SQL мы бы просто использовали WHERE Col1 LIKE '%string%' OR Col2 LIKE '%string%' etc.

Это код, который у меня есть в настоящее время:

 var members =
            Query()
                .Where(
                    x =>
                        x.Phone1.Contains(searchText) || x.Email1.Contains(searchText) ||
                        x.Phone2.Contains(searchText) || x.Email2.Contains(searchText) ||
                        x.FirstName.Contains(searchText) || x.LastName.Contains(searchText) ||
                        x.Fax1.Contains(searchText) || x.Username.Contains(searchText) || x.Address.Contains(searchText)

                        );
        return members;
  

Теперь, по моему мнению, это должно сработать … но это не так. Итак, я задумался… Должен быть лучший способ. Возможно, какое-то прогрессивное многоступенчатое построение выходных данных? Но я понятия не имею, как сделать это удобным для ресурсов способом. Любой удар в правильном направлении был бы весьма признателен!

Комментарии:

1. Ваш пример кода не возвращает результирующий набор, он возвращает неисполненный IQuerable<T> .

2. что Query() возвращает?

3. Мне неясно, спрашиваете ли вы, почему ваш текущий код «не работает», или вас беспокоит производительность, или читаемость кода, или что? Можете ли вы уточнить, на какой вопрос вы пытаетесь получить ответ?

4. Да, моя ошибка, я отключаю . ToList() в другом методе.

5. То, что я искал, — это другой способ объединения различных предложений where, чтобы сделать его более чистым. Пример, который я привел здесь, довольно прост… но у нас есть некоторые объекты, которым в некоторых редких случаях требуется поиск по более чем 100 полям, и это становится довольно уродливым.

Ответ №1:

Как упоминалось выше, вам нужно запросить объект. Что-то вроде:

 var members = dbContext.YourEntity            
            .Where(
                x =>
                x.Phone1.Contains(searchText) || x.Email1.Contains(searchText) ||
                x.Phone2.Contains(searchText) || x.Email2.Contains(searchText) ||
                x.FirstName.Contains(searchText) || x.LastName.Contains(searchText) ||
                x.Fax1.Contains(searchText) || x.Username.Contains(searchText) || x.Address.Contains(searchText)
                ).ToList();
  

Это идентично SQL-запросу, о котором вы упоминали выше.

Чтобы улучшить это, вам может потребоваться реструктурировать вашу базу данных. Вы могли бы создать реляционную сущность, в которой ваши телефонные номера находятся в одном объекте, электронные письма — в другом и так далее. Они будут ссылаться на ваших участников, тогда вы будете запрашивать меньшее количество полей (но тот же объем данных).