private static Expression CheckNullInPath( IReadOnlyList <Expression> steps, bool canBeNull, Expression compare, bool ignoreLast) { steps = steps ?? throw new ArgumentNullException(nameof(steps)); compare = compare ?? throw new ArgumentNullException(nameof(compare)); var result = compare; var combiner = canBeNull ? (Func <Expression, Expression, Expression>)Expression.OrElse : Expression.AndAlso; var comparer = canBeNull ? (Func <Expression, Expression, Expression>)Expression.Equal : Expression.NotEqual; var until = ignoreLast ? steps.Count - 1 : steps.Count; for (var i = until - 1; i >= 0; i--) { var property = steps[i]; if (ComparisonBuilder.CanBeNull(property.Type)) { result = combiner( comparer( property, Expression.Constant(null, typeof(object))), result); } } return(result); }
public Expression <Func <T, bool> > IsNullComparator <T>(ParameterExpression parameter, RsqlParser.ComparisonContext context) { parameter = parameter ?? throw new ArgumentNullException(nameof(parameter)); context = context ?? throw new ArgumentNullException(nameof(context)); var expressionPath = this._propertyAccessor.ParsePath(parameter, context.selector().GetText()); var value = (bool)ComparisonBuilder.GetSingleValue(typeof(bool), context); var lastNullableExpression = expressionPath.ExpressionSteps.LastOrDefault(e => ComparisonBuilder.CanBeNull(e.Type)); if (lastNullableExpression == null) { // Can never be null return(Expression.Lambda <Func <T, bool> >(Expression.Constant(!value), parameter)); } var result = Expression.Lambda <Func <T, bool> >( ComparisonBuilder.PathCanBeNull( expressionPath, Expression.Equal( lastNullableExpression, Expression.Constant(null, typeof(object)))), parameter); if (value) { return(result); } var body = Expression.Not(result.Body); result = Expression.Lambda <Func <T, bool> >(body, parameter); return(result); }