2011-10-07 14 views
16

voglio cercare questo:Linq to Entities (EF 4.1): Come eseguire un SQL LIKE con un carattere jolly nel mezzo ('% term% term%')?

Post Cereal 

e ottenere questo:

Post Honey Nut Cereal 

in cui le wild card sarebbero gli spazi.

So che potrei fare uno SPLIT e una serie di ANDs e Contains() e la traduzione in un'espressione Linq per ogni termine come un oggetto di specifica, ma non c'è un modo per onorare i caratteri jolly nel termine inviato a SQL ? Ho esaminato le funzioni SQL in cui è in Linq to SQL, ma non sono sicuro di cosa sia in Linq alle entità.

mi piacerebbe fare qualcosa di simile:

term = '%' + term.Replace(' ', '%') + '%'; 
db.table.where(p => System.Data.Objects.SqlClient.SqlFunctions 
        .SqlMethods.Like(p.fieldname, term)); 

Qualche suggerimento?

risposta

43

Credo che si potrebbe usare SqlFunctions.PatIndex:

dt.Table.Where(p => SqlFunctions.PatIndex(term, p.fieldname) > 0); 

SqlFunctions.PatIndex si comporta come l'operatore SQL LIKE. Supporta tutti i caratteri jolly standard, tra cui:

  • % Ogni stringa di zero o più caratteri.
  • _ (trattino basso) Qualsiasi carattere singolo.
  • [] Qualsiasi singolo carattere all'interno dell'intervallo specificato ([a-f]) o impostato ([abcdef]).
  • [^] Qualsiasi singolo carattere non compreso nell'intervallo specificato ([^ a-f]) o impostato ([^ abcdef]).

SqlFunctions.PatIndex è spesso disponibile quando lo SqlMethods.Like non è disponibile (anche all'interno controller MVC)

+1

Questo merita più voti. Questo ha funzionato perfettamente per me senza molta complessità. –

+0

Dr. Zim ha ragione, è stato alla ricerca di una soluzione per diverse ore e questo è di gran lunga il più semplice che ho trovato. – user1841243

+0

Ho provato questo in .NET e direttamente in TSQL e nessuno dei due modi ha funzionato per me. L'utilizzo di EF 5, .NET 4.5 e VS 2012 – Matt

5

È probabilmente più facile da aggirare LINQ e utilizzare un filtro Entity SQL:

var query - db.table.Where("TRIM(fieldname) LIKE @pattern"); 
query.Parameters.Add(new ObjectParameter("pattern", term)); // term == "%what%ever%" 

e il tipo di query attrezzi IQueryable<TEntity> in modo da poter applicare ulteriori operatori LINQ.

+0

Sto provando questo in LINQPad, ma ottengo questa eccezione: 'EntitySqlException: 'BusinessName' non può essere risolto nello scope o nel contesto corrente. Assicurati che tutte le variabili di riferimento siano incluse nello scope, che gli schemi richiesti siano caricati e che gli spazi dei nomi siano referenziati correttamente. Dove "BusinessName" è la colonna su cui cerco di filtrare. Non riesco a capire come superare questo. –

+0

@adrift È necessario configurare LINQPad con le informazioni di contesto, lo uso a malapena e quindi non posso davvero aiutare (IIRC ho appena fatto riferimento all'assieme con i tipi di contesto e entità). – Richard

+1

L'uso di Entity SQL è acutally l'unico modo per farlo: L2E non supporta questo tipo di ricerca con caratteri jolly. Per risolvere il tuo problema prova a usare 'it.BusinessName'. Le colonne in ESQL devono essere prefissate e 'it' è il prefisso predefinito - [qui] (http://stackoverflow.com/questions/6202036/entity-framework-v4-1-like/6202346#6202346) è un esempio completo della query . –

0

Giusto per chiarire il commento di Ladislav quanto riguarda it.BusinessName. Penso a ciò a cui si sta riferendo sta anteponendo il nome del campo con .it. La soluzione di cui sopra funziona finché si prefissa il nome del campo nella clausola where con it.. Inoltre non avevo bisogno del TRIM() nel mio caso.

var query - db.table.Where("it.fieldname LIKE @pattern"); 
query.Parameters.Add(new ObjectParameter("pattern", term)); // term == "%what%ever%" 

ha funzionato perfettamente in un database Oracle.