private Expression GetPropertyExpression(Expression expr, string propertyName, Type returnType) { if (TypeFns.IsNullableType(expr.Type)) { var nullBaseExpression = Expression.Constant(null, expr.Type); var test = Expression.Equal(expr, nullBaseExpression); expr = Expression.Convert(expr, TypeFns.GetNonNullableType(expr.Type)); Expression propExpr = Expression.PropertyOrField(expr, propertyName); propExpr = Expression.Convert(propExpr, TypeFns.GetNullableType(returnType)); var nullExpr = Expression.Constant(null, TypeFns.GetNullableType(returnType)); return(Expression.Condition(test, nullExpr, propExpr)); } else { return(Expression.PropertyOrField(expr, propertyName)); } }
private Expression BuildBinaryExpr(Expression expr1, Expression expr2, Operator op) { if (expr1.Type != expr2.Type) { if (TypeFns.IsNullableType(expr1.Type) && !TypeFns.IsNullableType(expr2.Type)) { expr2 = Expression.Convert(expr2, expr1.Type); } else if (TypeFns.IsNullableType(expr2.Type) && !TypeFns.IsNullableType(expr1.Type)) { expr1 = Expression.Convert(expr1, expr2.Type); } if (HasNullValue(expr2) && CannotBeNull(expr1)) { expr1 = Expression.Convert(expr1, TypeFns.GetNullableType(expr1.Type)); } else if (HasNullValue(expr1) && CannotBeNull(expr2)) { expr2 = Expression.Convert(expr2, TypeFns.GetNullableType(expr2.Type)); } } if (op == BinaryOperator.Equals) { return(Expression.Equal(expr1, expr2)); } else if (op == BinaryOperator.NotEquals) { return(Expression.NotEqual(expr1, expr2)); } else if (op == BinaryOperator.GreaterThan) { return(Expression.GreaterThan(expr1, expr2)); } else if (op == BinaryOperator.GreaterThanOrEqual) { return(Expression.GreaterThanOrEqual(expr1, expr2)); } else if (op == BinaryOperator.LessThan) { return(Expression.LessThan(expr1, expr2)); } else if (op == BinaryOperator.LessThanOrEqual) { return(Expression.LessThanOrEqual(expr1, expr2)); } else if (op == BinaryOperator.StartsWith) { var mi = TypeFns.GetMethodByExample((String s) => s.StartsWith("abc")); return(Expression.Call(expr1, mi, expr2)); } else if (op == BinaryOperator.EndsWith) { var mi = TypeFns.GetMethodByExample((String s) => s.EndsWith("abc")); return(Expression.Call(expr1, mi, expr2)); } else if (op == BinaryOperator.Contains) { var mi = TypeFns.GetMethodByExample((String s) => s.Contains("abc")); return(Expression.Call(expr1, mi, expr2)); } else if (op == BinaryOperator.In) { // TODO: need to generalize this past just 'string' var mi = TypeFns.GetMethodByExample((List <String> list) => list.Contains("abc"), expr1.Type); return(Expression.Call(expr2, mi, expr1)); } return(null); }