Come operatore in Entity Framework?

Stiamo cercando di implementare l’operatore “LIKE” in Entity Framework per le nostre quadro con campi stringa, ma non sembra essere supportato. Qualcun altro ha provato a fare qualcosa di simile?

Questo post del blog riassume il problema che stiamo avendo. Potremmo usare contiene, ma quello corrisponde solo al caso più banale per LIKE. Combinare contiene, startswith, endswith e indexof ci porta lì, ma richiede una traduzione tra i caratteri jolly standard e il codice Linq to Entities.

Questo è un vecchio post ora, ma per chiunque cerchi la risposta, questo link dovrebbe aiutare.

Versione breve:

Metodo SqlFunctions.PatIndex : restituisce la posizione iniziale della prima occorrenza di un modello in un’espressione specificata, o zeri se il modello non viene trovato, su tutti i tipi di dati di testo e carattere validi

Spazio dei nomi: System.Data.Objects.SqlClient Assembly: System.Data.Entity (in System.Data.Entity.dll)

Un po ‘di una spiegazione appare anche in questo thread del forum .

Non so davvero nulla di EF, ma in LINQ to SQL di solito esprimi una clausola LIKE usando String.Contains:

where entity.Name.Contains("xyz") 

si traduce in

 WHERE Name LIKE '%xyz%' 

(Usa StartsWith and EndsWith per altri comportamenti.)

Non sono del tutto sicuro che sia utile, perché non capisco cosa intendi quando dici di voler implementare LIKE. Se ho frainteso completamente, fammi sapere e cancellerò questa risposta 🙂

Ho avuto lo stesso problema.

Per ora, ho optato per il filtraggio Wildcard / Regex lato client basato su http://www.codeproject.com/Articles/11556/Converting-Wildcards-to-Regexes?msg=1423024#xx1423024xx – è semplice e funziona come previsto.

Ho trovato un’altra discussione su questo argomento: http://forums.asp.net/t/1654093.aspx/2/10
Questo post sembra promettente se si utilizza Entity Framework> = 4.0:

Usa SqlFunctions.PatIndex:

http://msdn.microsoft.com/en-us/library/system.data.objects.sqlclient.sqlfunctions.patindex.aspx

Come questo:

 var q = EFContext.Products.Where(x => SqlFunctions.PatIndex("%CD%BLUE%", x.ProductName) > 0); 

Nota: questa soluzione è solo per SQL Server, perché utilizza la funzione PATINDEX non standard.

Aggiornamento: in EF 6.2 c’è un operatore simile

 Where(i => DbFunctions.Like(searchstring ,like expression) 

C’è un operatore LIKE aggiunto in Entity Framework Core 2.0 :

 var query = from e in _context.Employees where EF.Functions.Like(e.Title, "%developer%") select e; 

Confronto con ... where e.Title.Contains("developer") ... è veramente tradotto in SQL LIKE piuttosto che in CHARINDEX che vediamo per il metodo Contains .

È specificamente menzionato nella documentazione come parte di Entity SQL. stai ricevendo un messaggio di errore?

 // LIKE and ESCAPE // If an AdventureWorksEntities.Product contained a Name // with the value 'Down_Tube', the following query would find that // value. Select value P.Name FROM AdventureWorksEntities.Product as P where P.Name LIKE 'DownA_%' ESCAPE 'A' // LIKE Select value P.Name FROM AdventureWorksEntities.Product as P where P.Name like 'BB%' 

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

se stai usando MS Sql, ho scritto 2 metodi di estensione per supportare il carattere% per la ricerca con caratteri jolly. (È richiesto LinqKit)

 public static class ExpressionExtension { public static Expression> Like(Expression> expr, string likeValue) { var paramExpr = expr.Parameters.First(); var memExpr = expr.Body; if (likeValue == null || likeValue.Contains('%') != true) { Expression> valExpr = () => likeValue; var eqExpr = Expression.Equal(memExpr, valExpr.Body); return Expression.Lambda>(eqExpr, paramExpr); } if (likeValue.Replace("%", string.Empty).Length == 0) { return PredicateBuilder.True(); } likeValue = Regex.Replace(likeValue, "%+", "%"); if (likeValue.Length > 2 && likeValue.Substring(1, likeValue.Length - 2).Contains('%')) { likeValue = likeValue.Replace("[", "[[]").Replace("_", "[_]"); Expression> valExpr = () => likeValue; var patExpr = Expression.Call(typeof(SqlFunctions).GetMethod("PatIndex", new[] { typeof(string), typeof(string) }), valExpr.Body, memExpr); var neExpr = Expression.NotEqual(patExpr, Expression.Convert(Expression.Constant(0), typeof(int?))); return Expression.Lambda>(neExpr, paramExpr); } if (likeValue.StartsWith("%")) { if (likeValue.EndsWith("%") == true) { likeValue = likeValue.Substring(1, likeValue.Length - 2); Expression> valExpr = () => likeValue; var containsExpr = Expression.Call(memExpr, typeof(String).GetMethod("Contains", new[] { typeof(string) }), valExpr.Body); return Expression.Lambda>(containsExpr, paramExpr); } else { likeValue = likeValue.Substring(1); Expression> valExpr = () => likeValue; var endsExpr = Expression.Call(memExpr, typeof(String).GetMethod("EndsWith", new[] { typeof(string) }), valExpr.Body); return Expression.Lambda>(endsExpr, paramExpr); } } else { likeValue = likeValue.Remove(likeValue.Length - 1); Expression> valExpr = () => likeValue; var startsExpr = Expression.Call(memExpr, typeof(String).GetMethod("StartsWith", new[] { typeof(string) }), valExpr.Body); return Expression.Lambda>(startsExpr, paramExpr); } } public static Expression> AndLike(this Expression> predicate, Expression> expr, string likeValue) { var andPredicate = Like(expr, likeValue); if (andPredicate != null) { predicate = predicate.And(andPredicate.Expand()); } return predicate; } public static Expression> OrLike(this Expression> predicate, Expression> expr, string likeValue) { var orPredicate = Like(expr, likeValue); if (orPredicate != null) { predicate = predicate.Or(orPredicate.Expand()); } return predicate; } } 

uso

 var orPredicate = PredicateBuilder.False(); orPredicate = orPredicate.OrLike(per => per.Name, "He%llo%"); orPredicate = orPredicate.OrLike(per => per.Name, "%Hi%"); var predicate = PredicateBuilder.True(); predicate = predicate.And(orPredicate.Expand()); predicate = predicate.AndLike(per => per.Status, "%Active"); var list = dbContext.Set().Where(predicate.Expand()).ToList(); 

in ef6 e dovrebbe tradurre in

 .... from People per where ( patindex(@p__linq__0, per.Name) <> 0 or per.Name like @p__linq__1 escape '~' ) and per.Status like @p__linq__2 escape '~' 

‘, @ p__linq__0 =’% He% llo% ‘, @ p__linq__1 =’% Ciao% ‘, @ p__linq_2 =’% attivo ‘

re: “ci piacerebbe essere in grado di eguagliare su blah blah foo bar foo? bar? foo * bar? e altri schemi complessi.” Non ho ancora provato questo (non ho ancora bisogno di ancora), ma hai provato a utilizzare System.Text.RegularExpressions.RegEx?

È ansible utilizzare un vero come in Link to Entities abbastanza facilmente

Inserisci

      searchingIn LIKE lookingFor   

al tuo EDMX in questo tag:

edmx: EDMX / edmx: Runtime / edmx: ConceptualModels / Schema

Ricorda anche lo spazio dei nomi nell’attributo

Quindi aggiungi una class di estensione nello spazio dei nomi sopra:

 public static class Extensions { [EdmFunction("DocTrails3.Net.Database.Models", "String_Like")] public static Boolean Like(this String searchingIn, String lookingFor) { throw new Exception("Not implemented"); } } 

Questo metodo di estensione verrà ora associato alla funzione EDMX.

Maggiori informazioni qui: http://jendaperl.blogspot.be/2011/02/like-in-linq-to-entities.html