0

汎用フィルター オブジェクトを表すクラスがあります

public class Filter
{
    public string column { get; set; }
    public string operator { get; set; }
    public string data { get; set; }
}

LambdaExpressionこのようなコードのおかげで変換できること

public LambdaExpression ToExpression( IQueryable query ) {
    LambdaExpression toReturn = null;
    ParameterExpression parameter = Expression.Parameter( query.ElementType, "p" );
    MemberExpression memberAccess = GetMemberExpression( column, parameter );
    ConstantExpression filter = Expression.Constant( Convert.ChangeType( data, memberAccess.Type ) );
    WhereOperation condition = (WhereOperation)StringEnum.Parse( typeof( WhereOperation ), operator );
    LambdaExpression lambda = BuildLambdaExpression( memberAccess, filter, parameter, condition, data );
    if ( toReturn == null ) {
        toReturn = lambda;
    }
    return toReturn;
}

要件に従って、次のように表現される、フィールドを照会するための一種のナビゲーション シンタックスをFilterメンバーに含めることができます。columnFieldA.FieldB.Description

  • FieldA プロパティから返された型 T の値を取得します
  • T の FieldB から返された T1 型の値を取得します
  • T2 の説明から返されたタイプ T2 の値を取得します

結果は次のようなラムダです。この結果を任意の拡張メソッドのp.FieldA.FieldB.Description == "data" パラメーターとして使用できます。WhereIQueryable

問題は、ナビゲーション クエリのメンバーの 1 つがNullable型の場合に発生します。その場合、FieldA が nullable であると仮定すると、正しいラムダは次のようになります。

p.FieldA != null && p.FieldA.FieldB.Description == "data"

MemberExpressionこのようなコードを使用してオブジェクトを構築するときに、このチェックを実装しようとしました

MemberExpression memberAccess = null;
foreach ( var property in column.Split( '.' ) ) {
    memberAccess = MemberExpression.Property( memberAccess ?? ( p as Expression ), property );
    Type memberType = memberAccess.Type;
    if ( memberType.IsGenericType && 
         memberType.GetGenericTypeDefinition() == typeof( Nullable<> ) ) {

        //Create here an expression of type : memberAccess != null
    }
}

これはプリミティブ型には適していますが、たとえば、EFEntityReferenceオブジェクト インスタンスなどの他のオブジェクト参照では機能しません。if前のような条件に別の条件を追加するだけでよいことはわかっています

if ( ( memberType.IsGenericType && 
       memberType.GetGenericTypeDefinition() == typeof( Nullable<> ) ) ||
       memberType.IsClass ) {
}

しかし、それはあまりにも多くの条件でラムダを生成するジェネリックが多すぎて、それらのほとんどが役に立たないように思えます。

null許容参照をより適切に個別化する方法はありますか?

4

1 に答える 1

3

null チェックを無条件にすることができます。null の値の型をチェックすることは違法ではありません。

于 2012-10-12T15:08:37.283 に答える