LINQ to Entities Поиск свойств текста для нескольких ключевых слов - PullRequest
7 голосов
/ 18 февраля 2009

Для веб-сайта, который я делаю, мы используем LINQ to Entities. Мне было поручено добавить поисковую функцию на сайт. Я пытаюсь найти наиболее элегантный способ поиска нескольких ключевых слов (введенных пользователем) в одном поле в базе данных. Позвольте мне привести пример.

Столбцы таблицы:

Name, Description

Пример строки:

"Cookie monster", "Fluffy, likes cookies and blue"

Поиск пользователя (разделитель не имеет значения):

"blue fluffy" 

В настоящее время я использую следующее:

    public List<SesameCharacters> SearchByKeywords(string keywords)
    {
        List<SesameCharacters> output = new List<SesameCharacters>();
        string[] k = keywords.ToLower().Split(' ');
        using (SesameStreet_Entities entities = new SesameStreet_Entities())
        {
            IQueryable<SesameCharacters> filter = entities.SesameCharacters;

            foreach (string keyword in k)
                filter = ForceFilter(filter, keyword);

            output = filter.ToList();
        }
        return output;
    }

    private IQueryable<SesameCharacters> ForceFilter(IQueryable<SesameCharacters> filter, string keyword)
    {
        return filter.Where(p => p.Description.ToLower().Contains(keyword));
    }

В настоящее время это работает, как и ожидалось, но я думаю, что это не лучшее решение проблемы. Я что-то упускаю из виду очевидное?

ПРИМЕЧАНИЕ: Это AND соответствие.

Ответы [ 4 ]

10 голосов
/ 08 июля 2010

Я обнаружил, что это работает для меня - это использование VB.Net с Entity Framework 4.0, но я уверен, что принцип переводит.

Этот выполняет запрос в стиле «ИЛИ»:

    Function Search(ByVal query As String) As IQueryable(Of Product)
    Dim queryWords As String() = query.Split()
    Dim entities As New Entities()

    Return entities.Products.Where(Function(p) queryWords.Any(Function(w) p.Description.Contains(w)))
End Function

А этот выполняет запросы в стиле «И»:

Function Search(ByVal query As String) As IQueryable(Of product)
    Dim queryWords As String() = query.Split()
    Dim entities As New Entities()

    Return entities.Products.Where(Function(p) queryWords.All(Function(w) p.Description.Contains(w)))
End Function
3 голосов
/ 18 февраля 2009

Похоже, что Linq to Entities не поддерживает содержит:

http://msdn.microsoft.com/en-us/library/bb738638.aspx

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

1 голос
/ 21 февраля 2009

как насчет вместо:

IQueryable<SesameCharacters> filter = entities.SesameCharacters;

        foreach (string keyword in k)
            filter = ForceFilter(filter, keyword);

        output = filter.ToList();

Do:

return (from c in entities.SesameCharacters
         where k.Contains(c..Description.ToLower())
         select c
         ).ToList();
0 голосов
/ 18 февраля 2009

Не относится к LINQ, но вы можете рассмотреть возможность использования SQL Server Полнотекстовый поиск , в то время как предикат СОДЕРЖИТ понимает логические операторы - И, ИЛИ, И НЕ.

Эта статья также может быть полезна: Динамически составлять предикаты выражений

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...