0

Ich versuche, eine Methode zu erstellen, die das Wo-Prädikat erstellen, um später auf einer Linq-Methode (Linq2NHibernate) zu verwenden. Was ich hier habe, ist eine Methode, die die Erstellung eines Ausdrucks ausführen, der in einer Abfrage Linq verwendet wird. Lassen Sie uns einige Code sehen.net NHibernate Linq Lambda-Ausdruck Verkettung

private Expression<Func<Model.FattureEmesse, bool>> getUserFilterExpression(FattureFilter filterStructure) 
{ 
    Expression<Func<Model.FattureEmesse, bool>> dataDocumentoFilter = f => 
    true; 

    Expression<Func<Model.FattureEmesse, bool>> dataFineValiditaFilter = f => 
    true; 

    var userFilterExpression = dataDocumentoFilter 
    .And(dataFineValiditaFilter) 
    .And(dataImportazioneFilter); 

    return userFilterExpression;    
} 

Der Ausdruck wird komplexer sein als eine einfache „immer wahr“, aber für das Problem habe ich habe ich das gleiche Verhalten. Der .Und Sie sehen, ist eine Erweiterung Methode (I hier auf SO für echte gefunden)

internal static class PredicateExtensions 
{ 
    public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expression1, Expression<Func<T, bool>> expression2) where T : Model.DomainModelObject 
    { 
     InvocationExpression invokedExpression = Expression.Invoke(expression2, expression1.Parameters.Cast<Expression>()); 

     return Expression.Lambda<Func<T, bool>>(Expression.And(expression1.Body, invokedExpression), expression1.Parameters); 
    } 
} 

Jetzt habe ich eine Business-Logik-Klasse mit einer Methode, die die Expression erstellt und übergibt es an den DAL-Manager zu sammeln. Diese Methode ruft einfach

var userFilterExpression = getUserFilterExpression(filterStructure); 
var securityFilterExpression = new BL.SecurityManager().getFilterExpression<Model.FattureEmesse>(user); 
var totalFilterExpression = userFilterExpression.And(securityFilterExpression); 

Wie man sehen kann ich noch einen Ausdruck aus dem Securitymanager abrufen (falls zweifeln Sie das Problem, occour selbst wenn ich Kette toghether der 2-Expression zu vermeiden) und rufen dann

Diese
var filteredFatture = new GenericDalManager().getFilteredList<Model.FattureEmesse>(maximumRows, startRowIndex, totalFilterExpression); 

ist, wo alles zusammengelegt, wird die Abfrage

public class GenericDalManager 
{ 
    internal IList<T> getFilteredList<T>(int maximumRows, int startRowIndex, Expression<Func<T, bool>> expressionResult) where T : Model.DomainModelObject 
    { 
     using (var session = PersistenceManager.Istance.GetSession()) 
     { 
     var items = (from o in session.Linq<T>() 
         orderby o.Id 
         select o); 

     var filteredItems = items.Where(expressionResult) 
            .Skip(startRowIndex) 
            .Take(maximumRows);      

     return filteredItems.ToList(); 
     } 
    } 
} 

So zu machen, wenn ich die Methode aufrufen, die Führen Sie die Abfrage aus, es gibt einen Fehler in dem .ToList() - Aufruf zurück, den Sie in der letzten Zeile sehen. Der Fehler ist Objektverweis nicht auf eine Instanz eines Objekts festgelegt. Und es tritt in NHibernate.Linq auf. Das Problem scheint mit der And-Methode verwandt zu sein, da es funktioniert, wenn ich einen einfachen Ausdruck ohne Verkettung mache. Was ist los? Wenn ich den Ausdruck einfach vor der Übergabe an die genericDalManager.getFilteredList-Methode kompiliere, funktioniert alles, aber der Ausdruck wird nicht als Abfrage für die Datenbank ausgewertet (offensichtlich erzeugt der Ausdruck "always true" keine interessante where-Klausel, aber ich brauche das, um einen komplexeren Filter zu machen). Die seltsame Sache ist, dass, wenn ich nicht die beiden "immer wahr" -Ausdruck in der Methode getUserFiltreExpression verketten, aber ich nur die erste zurückgeben, alles funktioniert gut. Auch wenn nach dem gleichen Ausdruck wird mit dem Ergebnis von BL.SecurityManager() getFilterExpression (Benutzer) aufgerufen werden. Und übrigens, um dieses Problem zu testen, gibt dieser letzte Aufruf einen anderen "immer wahr" -Ausdruck zurück.

Wer hilft mir bitte ... Ich werde verrückt!

Antwort

1

Ich denke, das Problem ist, dass Sie und mit dem Ergebnis des Ausdrucks (nach dem Aufruf) und nicht mit dem Ausdruck selbst. Dieser Ausdruck kann wahrscheinlich nicht geparst werden. Möglicherweise müssen Sie auch AndAlso (logische und) insead von And (bitweise und) und vielleicht die Parameter

Rebind