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成员column可以包含一种用于查询字段的导航语法,其表达FieldA.FieldB.Description方式如下:

  • 获取从 FieldA 属性返回的类型 T 的值
  • 获取T的FieldB返回的类型T1的值
  • 获取 T2 的描述返回的类型 T2 的值

结果是一个像这样的 lambda:p.FieldA.FieldB.Description == "data" 我可以将此结果用作Where任何扩展方法的参数IQueryable

当导航查询的成员之一是Nullable类型时,问题就出现了。在这种情况下,假设 FieldA 可以为空,正确的 lambda 应该是

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

但在我看来,这似乎太通用了,产生了一个条件太多的 lambda,其中大多数可能没用。

有没有办法更好地区分可空引用?

4

1 回答 1

3

您可以无条件地进行空检查。检查 null 的值类型不是非法的。

于 2012-10-12T15:08:37.283 回答