2017-07-13 2 views
2

Ich versuche, einen Ausdruck von LINQ/SQL Server aufgelöst zu bekommen, aber es scheint, es kann nicht mit dem Ausdruck umgehen und überspringt es nur ganz (es funktioniert jedoch auf einem In-Memory-Dataset) .Ausdruck nicht von SQL Server ausgewertet

public static Func<TSource, bool> WhereNotNullClause<TSource>(string propertyName) 
    { 
     var type = typeof(TSource); 
     var expression = Expression.Parameter(type, "p"); 
     var propertyNameReference = Expression.Property(expression, propertyName); 
     var propertyValueReference = Expression.Constant(null); 

     return Expression.Lambda<Func<TSource, bool>>(
      Expression.NotEqual(propertyNameReference, propertyValueReference), 
      new[] { expression }).Compile(); 
    } 

wie folgt aufgerufen:

var whereNotNullSelector = Expressions.WhereNotNullClause<ContactItem>("property"); 
var contactItems = context.ContactItems.Where(whereNotNullSelector).ToList(); 

Die SQL erzeugt beinhaltet nicht die where-Klausel, so dass die in dem ausgeführt wird, scheint nach der Abfrage löst. Auf welche Dinge muss ich noch achten, bevor ich dies richtig lösen kann?

Antwort

3

Ihre Methode gibt eine Func anstelle einer Expression zurück. Der Code muss Enumerable.Where anstelle von Queryable.Where verwenden. Dies bedeutet, dass die Daten materialisiert werden müssen, der gesamte Datensatz aus der Datenbank gezogen und der Filter lokal ausgeführt werden muss. Ändern Sie einfach den Rückgabetyp einen Ausdruck zu sein und die .Compile entfernen:

public static Expression<Func<TSource, bool>> WhereNotNullClause<TSource>(string propertyName) 
{ 
    var type = typeof(TSource); 
    var expression = Expression.Parameter(type, "p"); 
    var propertyNameReference = Expression.Property(expression, propertyName); 
    var propertyValueReference = Expression.Constant(null); 

    return Expression.Lambda<Func<TSource, bool>>(
     Expression.NotEqual(propertyNameReference, propertyValueReference), 
     new[] { expression }); 
} 

einige zusätzliche Lese here auf, warum Sie Expression statt Func. Stellen Sie sich Ausdrücke als Daten und nicht als tatsächliche Delegaten vor. Das bedeutet, dass Linq to SQL den Ausdrucksbaum in SQL konvertieren kann, während ein Func im Wesentlichen ein schwarzes Feld ist.

Verwandte Themen