0

後でlinq whereメソッド(Linq2NHibernate)で使用するwhere述語を作成するメソッドを作成しようとしています。 ここで私が持っているのは、クエリLinqで使用される式の作成を実行するメソッドです。 のは、いくつかのコード.net NHibernate Linqラムダ式連鎖

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;    
} 

を見てみましょう表現は、単純な「常に真」よりも複雑になりますが、問題のために、私は同じ動作を持っています。あなたが見る .ANDは、拡張メソッド(私は本当のためにSO上でここに見つける)

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); 
    } 
} 

は、今、私が作成した数式を収集し、DALのマネージャーにそれを渡す方法とビジネスロジッククラスを持っています。そして、あなたは、私はセキュリティマネージャから別の表現を取得見ることができるようにする方法は、単純に(問題、場合にあなたが疑うoccour私は2発現toghetherチェーンに避けていても)

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

を呼び出し と

を呼び出します
var filteredFatture = new GenericDalManager().getFilteredList<Model.FattureEmesse>(maximumRows, startRowIndex, totalFilterExpression); 

すべてがそうクエリ

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(); 
     } 
    } 
} 

を作るためにtoghether置かれる場合、私は、そのメソッドを呼び出すとき、これは、ありますクエリを実行すると、最後の行に表示される.ToList()呼び出しでエラーが返されます。 エラーは オブジェクト参照がオブジェクトのインスタンスに設定されていません。 それはNHibernate.Linqで発生します。 問題はAndメソッドと関連しているようですが、チェーンを使わずに単純な式を作成すると動作します。 どうしたの? genericDalManager.getFilteredListメソッドに渡す式を単純にコンパイルすると、すべて正常に動作しますが、式をデータベース上のクエリとして評価することはありません(明らかに「常に真」の式は興味深いwhere句を生成しません。より複雑なフィルタを行うためには、これが必要です)。 奇妙なことは、メソッドgetUserFiltreExpressionで2つの "常に真の"式をチェーンしないで、最初のものだけを返した場合、すべて正常に動作するということです。同じ式の後にBL.SecurityManager()。getFilterExpression(user)呼び出しの結果が連鎖されている場合でも。 そして、この問題をテストするために、この最後の呼び出しは別の "常に真の"式を返します。

誰でも助けてください...私は怒っています!

答えて

1

私は問題があなたと式の結果(呼び出し後)で、式自体ではないと思います。その式はおそらく解析できません。あなたはまた、And(論理的および)And(ビット単位および)とおそらくパラメータを再結合することができます。