2017-07-17 1 views
2

Zum Beispiel implementieren:benutzerdefinierte Erweiterung-Funktion "IN" in C# (LINQ-2-Entities)

.Contains (...) in Linq2Entities supporte und auf "IN" SQL-Ausdruck umgewandelt.

ich wan diese Abfrage neu zu schreiben:

var foundExntities = myDbContext.MyEntityes.Where(o => new List<int> {111, 222, 333).Contains(o.ID)).ToList() 

in Form wie es:

var foundExntities = myDbContext.MyEntityes.Where(o => o.ID.In(111, 222, 33)).ToList() 

Wie kann ich dementsprech individuelle In (...) Erweiterung-Funktion schreiben?

+3

Ich empfehle Sie nicht. Das Definieren von Erweiterungsmethoden für "int" ist sehr verwirrend, wenn diese in Kontexte münden, in denen sie nicht verwendet werden können (und sie so zu schreiben, dass sie überall verwendet werden können, scheint es nicht wert zu sein). Abgesehen davon glaube ich nicht, dass Sie * können * - die Methode müsste von den EF-Ausdrucksbaum-Parsern erkannt werden, und ich denke nicht, dass diese Erweiterungspunkte haben. (Obwohl ich mit EF selbst nicht vertraut genug bin, um das sicher zu sagen.) Ich nehme an, Sie könnten die "IQueryable" -Implementierung einpacken, aber selbst das scheint weit mehr Ärger als es wert ist. –

+0

Es ist möglich, mit 'params int []' eine variable Anzahl ganzzahliger Argumente zu deklarieren (siehe https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/how-to -add-custom-methods-for-linq-queries) lehnte ich das Erstellen einer benutzerdefinierten Aggregatmethode wie in EF ab. Es kann solche Probleme wie LINQ to Entities die Methode nicht erkennen, da die benutzerdefinierte Methode manchmal nicht direkt in SQL-Abfrage übersetzt. –

+0

Ich möchte nur ** gut bekannt für EF (LINQ-2-SQL) Ausdruck ** zu solchen Makro-Funktion zu extrahieren. Diese Funktion erweitert nur meinen Query-Tree. –

Antwort

3

Wie kann ich entsprechende benutzerdefinierte In (...) Extension-Funktion schreiben?

Sie können nicht ohne auch einen vollwertigen Abfrage-Provider zu schreiben, die den Ausdrucksbaum wandelt durch Ihre individuelle Erweiterungsmethoden und Übersetzungs sie entsprechend (ähnlich LINQKitAsExpandable() Implementierung).

Was können Sie tun, ist aber eine benutzerdefinierte IQueryable<T> Erweiterungsmethode mit der Einschränkung zu schaffen, dass es nur mit LINQ Methode Syntax verwendet werden könnte und nur mit Root-abfragbaren Operatoren:

public static partial class QueryableExtensions 
{ 
    public static IQueryable<T> WhereIn<T, V>(this IQueryable<T> source, Expression<Func<T, V>> valueSelector, params V[] values) 
    { 
     var condition = Expression.Call(
      typeof(Enumerable), "Contains", new[] { typeof(V) }, 
      Expression.Constant(values), valueSelector.Body); 
     var predicate = Expression.Lambda<Func<T, bool>>(condition, valueSelector.Parameters); 
     return source.Where(predicate); 
    } 
} 

der auf Ihre Probe anwendbar ist wie:

var foundEntities = myDbContext.MyEntityes.WhereIn(o => o.ID, 111, 222, 33).ToList(); 
+0

Vielen Dank Ivan! –

Verwandte Themen