2009-02-18 4 views
7

Pour un site Web, nous utilisons LINQ to Entities. J'ai été chargé d'ajouter des fonctionnalités de recherche sur le site. J'essaie de trouver le moyen le plus élégant de rechercher plusieurs mots-clés (utilisateur entré) sur un seul champ dans la base de données. Permettez-moi de donner un exemple.LINQ to Entities Recherche de propriétés textuelles pour plusieurs mots clés

colonnes de la table:

Name, Description 

Exemple ligne:

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

Recherche d'utilisateur (delimiter n'a pas d'importance):

"blue fluffy" 

Actuellement, je me sers de ce qui suit:

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)); 
    } 

Cela fonctionne actuellement comme prévu mais j'imagine que ce n'est pas la meilleure solution au problème. Suis-je en train de manquer quelque chose d'évident?

REMARQUE: Ceci correspond à AND correspondant.

+0

bizarre, une réponse était ici, j'ai voté vers le haut, puis parce que je pensais que c'était mal, puis je suis allé voter pour le sauvegarder parce que c'était juste, maintenant c'est parti. – jfar

+1

Oui, il y avait une réponse de casperOne mais quelqu'un doit l'avoir développé. Il a suggéré d'utiliser un proc stocké, ce qui est ce qui penche vers maintenant. –

+0

Je suis dans la même situation ... Avez-vous trouvé une solution avec LinqToEntities, ou avez-vous fini par utiliser une procédure stockée? – Kjensen

Répondre

3

Ressemble LINQ to Entities ne prend pas en charge contient:

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

Je roulerais ma requête pour celui-ci. Vous allez probablement vouloir un contrôle total sur les requêtes de recherche de texte si vous découvrez que ces types de recherches deviennent des problèmes de performance.

1

que diriez-vous au lieu de:

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

car cela correspond à la description complète des mots-clés. Ce que je cherche, c'est de faire correspondre plusieurs mots individuels à de nombreux mots individuels. –

10

J'ai trouvé cela a fonctionné pour moi - cela utilise VB.Net avec Entity Framework 4.0, mais je suis sûr que le principe se traduit.

Celui-ci fait le "OU" requête de style:

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 

Et celui-ci ne "ET" requêtes de style:

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 
+1

Note - s'avère que cela fonctionne avec EF4 mais pas avec Linq à Sql en 3.5. – RichardW1001

+0

+1 - J'ai cherché partout une solution à ce problème ces derniers jours. Je n'ai pas pensé à le faire comme ça. – bernhof