2010-01-06 5 views
5

J'ai un cas dans mon application où l'utilisateur peut rechercher une liste de termes. La recherche doit effectuer trois passages dans l'ordre suivant:Linq to Sql une requête de recherche par mot-clé

  • Un pour une correspondance exacte de ce qu'ils ont saisi. Fait, facile.
  • Un où tous les mots (individuellement) correspondent. Fait, aussi facile.
  • un des mots correspondent ... comment?

Essentiellement, comment puis-je, dans LINQ to SQL, dis-le faire:

select * from stuff s where s.Title like '%blah%' || s.Title like '%woo&' || s.Title like '%fghwgads%' || s.Title like... 

Et ainsi de suite?

+0

Vous devriez savoir que ce genre de chose est vraiment mieux géré par la recherche de texte intégral. La version 'LIKE '% xyz%'' sera exécutée, mais les performances seront nulles. – Aaronaught

Répondre

7

Cela pourrait être un dur ... Je pense que vous auriez à écrire votre propre opérateur.

(Mise à jour:. Oui, je l'ai testé, ça marche)

public static class QueryExtensions 
{ 
    public static IQueryable<TEntity> LikeAny<TEntity>(
     this IQueryable<TEntity> query, 
     Expression<Func<TEntity, string>> selector, 
     IEnumerable<string> values) 
    { 
     if (selector == null) 
     { 
      throw new ArgumentNullException("selector"); 
     } 
     if (values == null) 
     { 
      throw new ArgumentNullException("values"); 
     } 
     if (!values.Any()) 
     { 
      return query; 
     } 
     var p = selector.Parameters.Single(); 
     var conditions = values.Select(v => 
      (Expression)Expression.Call(typeof(SqlMethods), "Like", null, 
       selector.Body, Expression.Constant("%" + v + "%"))); 
     var body = conditions.Aggregate((acc, c) => Expression.Or(acc, c)); 
     return query.Where(Expression.Lambda<Func<TEntity, bool>>(body, p)); 
    } 
} 

Ensuite, vous pouvez appeler cela avec:

string[] terms = new string[] { "blah", "woo", "fghwgads" }; 
var results = stuff.LikeAny(s => s.Title, terms); 

post-scriptum Vous devrez ajouter les espaces de noms System.Linq.Expressions et System.Data.Linq.SqlClient à vos espaces de noms pour la classe QueryExtensions.

+0

Cela a fonctionné! Je vous remercie! – Dusda

+0

J'ai utilisé le code dans Linq to Entities, et j'obtiens cette erreur: LINQ to Entities ne reconnaît pas la méthode 'Boolean Like (System.String, System.String)', et cette méthode ne peut pas être traduite dans une expression de magasin. –