2010-01-06 11 views
5

Ho un caso nella mia applicazione in cui l'utente può cercare un elenco di termini. La ricerca deve effettuare tre passaggi nel seguente ordine:Da Linq a Sql qualsiasi query di ricerca di parole chiave

  • Uno per una corrispondenza esatta di ciò che hanno inserito. Fatto, facile
  • Uno dove tutte le parole (singolarmente) corrispondono. Fatto, anche facile.
  • Uno dove qualsiasi delle parole corrisponde ... come?

In sostanza, come faccio, in LINQ to SQL, lo dico per fare questo:

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

E così via?

+0

Dovresti sapere che questo tipo di cose è meglio gestito dalla ricerca full-text. Verrà eseguita la versione 'LIKE '% xyz%'', ma le prestazioni faranno schifo. – Aaronaught

risposta

7

Questo potrebbe essere un problema difficile ... Penso che dovresti scrivere il tuo operatore.

(Aggiornamento:. Sì, ho testato, funziona)

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

Poi si potrebbe chiamare questo con:

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

P.S. È necessario aggiungere gli spazi dei nomiagli spazi dei nomi per la classe QueryExtensions.

+0

Ha funzionato! Grazie! – Dusda

+0

Ho usato il codice in Linq su Entities e ottengo questo errore: LINQ to Entities non riconosce il metodo metodo "Boolean Like (System.String, System.String)" e questo metodo non può essere tradotto in un'espressione di archivio. –

Problemi correlati