2017-07-20 8 views
1

データベースDDLを実行時に動的Linqに変換してフィルタを定義するこのコードがあります。一部のフィルタがnullになる子プロパティを参照する点を除いて、コードは機能します。ルールが適用されると、nullによって文全体が爆発します。ダイナミックLinqがヌルプロパティを許容しない

例として:

// filter is to see if ParentObject.ChildObject.ChildProperty > 1 
var param = Expression.Parameter(typeof(ParentObject)); 
var nullExpression = Expression.NotEqual(Expression.PropertyOrField(param, "ChildObject"), Expression.Constant(null)); 
var propertyExpression = Expression.Constant(ChildProperty); 
var filterExpression = Expression.MakeBinary(ExpressionType.GreaterThan, propertyExpression, typeof(ChildObject)); 
var finalExpression = Expression.Add({nullExpression, propertyExpression}); 

var compiledExpression = Expression.Lambda<Func<T, bool>>(finalExpression, param).Compile() //Compilation will succeed 
var isTrue = compiledExpression(ParentObject); //If ChildObject is null, this will explode 

私は、実行時にオブジェクトと(filterExpressionとして定義)フィルタを受けるので、NULLプロパティが見つかった場合、私は「エスケープ」LINQの配列にいくつかの方法が必要です。残念ながら、nullExpressionの結果に関係なく、filterExpressionが爆発するので、Nullチェックを追加することは役に立たないようです。私は動的なLinqを間違って書いたのか、これについて別の方法があるのか​​どうかはわかりません。何か案は?

例外

System.NullReferenceException: Object reference not set to an instance of an object. 
    at lambda_method(Closure , ParentObject) 
+3

を内蔵しているとしてあなたはコメントを見て、一例としてこれを使用することができるはずですか? –

+0

例外が追加されました。これはSystem.NullReferenceExceptionです。 – ChargerIIC

+0

@ChargerIIC、これは予想されます。 'ParentObject.ChildObject!= null && ParentObject.ChildObject.ChildProperty> 1 ' – Nkosi

答えて

2

コンセプトの証明として使用され、次のユニットテストを確認します。

[TestClass] 
public class UnitTest5 { 
    [TestMethod] 
    public void _MyTestMethod1() { 
     var target = new ParentObject { 
      ChildObject = new ChildObject { 
       ChildProperty = 5 
      } 
     }; 
     Assert.IsTrue(TestMethod1(target)); 
    } 

    [TestMethod] 
    public void _MyTestMethod2() { 
     var target = new ParentObject { 

     }; 
     Assert.IsFalse(TestMethod1(target)); 
    } 

    public bool TestMethod1<T>(T ParentObject) { 

     // filter is to see if ParentObject.ChildObject.ChildProperty > 1    
     // p => p.ChildObject != null && p.ChildObject.ChildProperty > 1 

     // p => ... 
     var param = Expression.Parameter(typeof(T)); 
     // p => p.ChildObject 
     var childObjectExpression = Expression.PropertyOrField(param, "ChildObject"); 
     // p => p.ChildObject != null 
     var nullExpression = Expression.NotEqual(childObjectExpression, Expression.Constant(null)); 
     // p => p.ChildObject.ChildProperty 
     var childPropertyExpression = Expression.Property(childObjectExpression, "ChildProperty"); 
     // p => p.ChildObject.ChildProperty > 1 
     var greaterThanExpression = Expression.MakeBinary(ExpressionType.GreaterThan, childPropertyExpression, Expression.Constant(1)); 
     // p => p.ChildObject != null && p.ChildObject.ChildProperty > 1 
     var finalExpression = Expression.AndAlso(nullExpression, greaterThanExpression); 

     var compiledExpression = Expression.Lambda<Func<T, bool>>(finalExpression, param).Compile();//Compilation will succeed 
     var isTrue = compiledExpression(ParentObject); 
     return isTrue; 
    } 

    public class ParentObject { 
     public ChildObject ChildObject { get; set; } 
    } 

    public class ChildObject { 
     public int ChildProperty { get; set; } 
    } 
} 

ダイナミックな表現が

私が実際に起こるんどのようなコードを爆発直面したことはありません
関連する問題