2009-05-07 11 views
335

Ho una procedura in SQL che sto cercando di trasformare in Linq:Come fare SQL Come% in Linq?

SELECT O.Id, O.Name as Organization 
FROM Organizations O 
JOIN OrganizationsHierarchy OH ON O.Id=OH.OrganizationsId 
where OH.Hierarchy like '%/12/%' 

La linea Sono molto preoccupato è:

where OH.Hierarchy like '%/12/%' 

Ho una colonna che memorizza la gerarchia come/1/3/12/ad esempio, quindi uso%/12 /% per cercarlo.

La mia domanda è, qual è il Linq o .NET equivalente all'utilizzo del segno di percentuale?

+1

La tua domanda ha almeno 5 voti per il tag [tag: like-operator]. Potrei cortesemente chiedere di suggerire [tag: sql-like] come [sinonimo] (http://stackoverflow.com/tags/like-operator/synonyms)? – Kermit

+1

Ovviamente. Fatto. –

risposta

469
.Where(oh => oh.Hierarchy.Contains("/12/")) 

È anche possibile utilizzare .StartsWith() o .EndsWith().

+2

L'utilizzo di StartsWith() o EndsWith() genererà una query? Voglio dire, il codice verrà tradotto in una query o i risultati verranno filtrati nell'oggetto dopo il recupero dal DB? – Novice

+5

No. StartsWith() e EndsWith() fanno parte del predicato/filtro. L'esecuzione continua a essere posticipata. – andleer

+2

provato che ha ottenuto NullReferenceException: riferimento oggetto non impostato su un'istanza di un oggetto. Quindi non mi piace quando nel mio caso a.Address1.StartsWith (Address1) e a.Address1 è nullo – MikeT

36

Suppongo che tu stia utilizzando Linq-to-SQL * (vedi nota sotto). In tal caso, utilizzare string.Contains, string.StartsWith e string.EndsWith per generare SQL che utilizza l'operatore SQL LIKE.

from o in dc.Organization 
join oh in dc.OrganizationsHierarchy on o.Id equals oh.OrganizationsId 
where oh.Hierarchy.Contains(@"/12/") 
select new { o.Id, o.Name } 

o

from o in dc.Organization 
where o.OrganizationsHierarchy.Hierarchy.Contains(@"/12/") 
select new { o.Id, o.Name } 

Nota: * = se si utilizza l'ADO.Net Entity Framework (EF/L2E) in .net 3.5, essere consapevoli del fatto che non farà lo stesso traduzione come Linq-to-SQL. Sebbene L2S faccia una traduzione corretta, L2E v1 (3.5) si tradurrà in un'espressione t-sql che imporrà una scansione completa della tabella sulla tabella su cui si sta eseguendo la query, a meno che non ci sia un altro discriminatore migliore nella clausola where o nei filtri join.
Aggiornamento: Questo è corretto in EF/L2E v4 (.net 4.0), quindi genererà un SQL LIKE proprio come fa L2S.

+1

+1 per commenti su Entity Framework – surfen

+0

Non c'è bisogno di sfuggire alle stringhe con il segno '@' ma mi rendo conto che potrebbe essere solo una buona convenzione da seguire. – andleer

27

Se si utilizza VB.NET, la risposta sarà "*". Ecco come dovrebbe apparire la tua clausola where ...

Where OH.Hierarchy Like '*/12/*' 

Nota: "*" Corrisponde a zero o più caratteri. Here is the msdn article for the Like operator.

+0

L'operatore VB Like traduce in chiamate L2S? (Non ne ho idea.) – andleer

+8

Sì, l'operatore VB Like viene tradotto nella versione SQL di like quando utilizzato in un'espressione di query LINQ. Inoltre, l'operatore VB Like non è limitato alle espressioni di query. – robertz

+1

Ho visto che esisteva al di fuori delle operazioni LINQ. Roba buona. +1 – andleer

230

Utilizzare questa:

from c in dc.Organization 
where SqlMethods.Like(c.Hierarchy, "%/12/%") 
select *; 
+16

questo è davvero utile se si desidera utilizzare la combinazione di pattern più complicata fornita dal comando like. Ad esempio, se si desidera verificare la presenza di due numeri (anziché 12), è possibile utilizzare questa espressione: SqlMethods.Like (c.Hierarchy, "%/[0-9] [0-9] /%") , vedere questo http://msdn.microsoft.com/en-us/library/aa933232(SQL.80).aspx – viggity

+0

questo è anche molto utile se si desidera consentire agli utenti esperti di pre-caricare la% iniziale costosa, dove usare StartsWith o Contains non dà al power user questa flessibilità –

+6

Come si usa 'SqlMethods' usando" notazione punto "? –

7

Bene indexOf anche per me

var result = from c in SampleList 
where c.LongName.IndexOf(SearchQuery) >= 0 
select c; 
+1

Questa dovrebbe essere la risposta accettata. IndexOf si traduce in CHARINDEX in sql. Questo potrebbe essere più veloce di LIKE. Ma a parte questo, offre la possibilità di costruire query di ricerca come '% some% thing%'. Dove "alcuni" devono essere posizionati prima di "cosa", cosa che non può essere eseguita con Contains. –

1

Prova questa, questo funziona bene per me

from record in context.Organization where record.Hierarchy.Contains(12) select record; 
0

faccio sempre questo:

from h in OH 
where h.Hierarchy.Contains("/12/") 
select h 

lo so io non uso la dichiarazione del genere, ma è un lavoro bene in lo sfondo è questo tradotto in una query con una dichiarazione simile.

+0

In che modo la tua risposta è diversa dalla risposta accettata (risposta 7 anni fa) o altre risposte? Che valore aggiunge? –

3

utilizzare tale codice

try 
{ 
    using (DatosDataContext dtc = new DatosDataContext()) 
    { 
     var query = from pe in dtc.Personal_Hgo 
        where SqlMethods.Like(pe.nombre, "%" + txtNombre.Text + "%") 
        select new 
        { 
         pe.numero 
         , 
         pe.nombre 
        }; 
     dgvDatos.DataSource = query.ToList(); 
    } 
} 
catch (Exception ex) 
{ 
    string mensaje = ex.Message; 
} 
0

Contiene viene utilizzato in Linq, Proprio come Come viene utilizzato in SQL.

string _search="/12/"; 

. . .

.Where(s => s.Hierarchy.Contains(_search)) 

È possibile scrivere lo script SQL in LINQ come a seguire:

var result= Organizations.Join(OrganizationsHierarchy.Where(s=>s.Hierarchy.Contains("/12/")),s=>s.Id,s=>s.OrganizationsId,(org,orgH)=>new {org,orgH}); 
2

Nel caso in cui non sono corrispondenti stringhe numeriche, sempre bene avere caso comune:

.Where(oh => oh.Hierarchy.ToUpper().Contains(mySearchString.ToUpper())) 
0

Per coloro come se stessi qui come me, cercando un modo per un metodo "SQL Like" in LINQ, ho qualcosa che funziona molto bene.

Sono in un caso in cui non è possibile modificare il database in alcun modo per modificare le regole di confronto delle colonne. Quindi devo trovare un modo nel mio LINQ per farlo.

Sto usando il metodo di supporto SqlFunctions.PatIndex strega agire in modo simile al vero operatore SQL LIKE.

prima ho bisogno elencare tutti i possibili segni diacritici (una parola che ho appena appreso) del valore di ricerca per ottenere qualcosa di simile:

déjà  => d[éèêëeÉÈÊËE]j[aàâäAÀÂÄ] 
montreal => montr[éèêëeÉÈÊËE][aàâäAÀÂÄ]l 
montréal => montr[éèêëeÉÈÊËE][aàâäAÀÂÄ]l 

e poi in LINQ per exemple:

var city = "montr[éèêëeÉÈÊËE][aàâäAÀÂÄ]l"; 
var data = (from loc in _context.Locations 
        where SqlFunctions.PatIndex(city, loc.City) > 0 
        select loc.City).ToList(); 

Quindi per le mie esigenze ho scritto un metodo Helper/Extension

public static class SqlServerHelper 
    { 

     private static readonly List<KeyValuePair<string, string>> Diacritics = new List<KeyValuePair<string, string>>() 
     { 
      new KeyValuePair<string, string>("A", "aàâäAÀÂÄ"), 
      new KeyValuePair<string, string>("E", "éèêëeÉÈÊËE"), 
      new KeyValuePair<string, string>("U", "uûüùUÛÜÙ"), 
      new KeyValuePair<string, string>("C", "cçCÇ"), 
      new KeyValuePair<string, string>("I", "iîïIÎÏ"), 
      new KeyValuePair<string, string>("O", "ôöÔÖ"), 
      new KeyValuePair<string, string>("Y", "YŸÝýyÿ") 
     }; 

     public static string EnumarateDiacritics(this string stringToDiatritics) 
     { 
      if (string.IsNullOrEmpty(stringToDiatritics.Trim())) 
       return stringToDiatritics; 

      var diacriticChecked = string.Empty; 

      foreach (var c in stringToDiatritics.ToCharArray()) 
      { 
       var diac = Diacritics.FirstOrDefault(o => o.Value.ToCharArray().Contains(c)); 
       if (string.IsNullOrEmpty(diac.Key)) 
        continue; 

       //Prevent from doing same letter/Diacritic more than one time 
       if (diacriticChecked.Contains(diac.Key)) 
        continue; 

       diacriticChecked += diac.Key; 

       stringToDiatritics = stringToDiatritics.Replace(c.ToString(), "[" + diac.Value + "]"); 
      } 

      stringToDiatritics = "%" + stringToDiatritics + "%"; 
      return stringToDiatritics; 
     } 
    } 

Se qualcuno di voi ha suggerito di migliorare questo metodo, sarò felice di sentirvi.

Problemi correlati