public void TestStringToNullable()
 {
     Assert.AreEqual(typeof(string), NullableUtils.ToNullable(typeof(string)));
 }
 public void TestNullableIntToNullable()
 {
     Assert.AreEqual(typeof(int?), NullableUtils.ToNullable(typeof(int?)));
 }
 public void TestStructToNullable()
 {
     Assert.AreEqual(typeof(TestStruct?), NullableUtils.ToNullable(typeof(TestStruct)));
 }
Beispiel #4
0
        private void VisitFirst(FunctionCall functionCall)
        {
            if (functionCall.Parameters.Count != 1 && functionCall.Parameters.Count != 2)
            {
                throw new SqlErrorException("'first' must contain either one or two parameters");
            }

            if (!(functionCall.Parameters[0] is ScalarExpression scalarExpression))
            {
                throw new SqlErrorException("'first' first parameter must be a scalar expression");
            }

            scalarExpression.Accept(this);
            var column = PopStack();

            //Check that is in an array (IEnumerable)
            if (!ArrayUtils.IsArray(column.Type))
            {
                throw new SqlErrorException("'first' first parameter must be an array/list.");
            }

            //Get the type that the array contains
            var elementType = ArrayUtils.GetArrayElementType(column.Type);

            Expression lambda = null;

            if (functionCall.Parameters.Count == 2)
            {
                if (!(functionCall.Parameters[1] is SqlParser.Expressions.LambdaExpression lambdaExpression))
                {
                    throw new SqlErrorException("'first' second parameter must be a lambda expression");
                }

                if (lambdaExpression.Parameters.Count != 1)
                {
                    throw new SqlErrorException("'first' lambda expression can only have one input parameter");
                }

                //Add the type to the lambda settings in the base visitor
                if (_lambdaParameters == null)
                {
                    _lambdaParameters = new Stack <Dictionary <string, ParameterExpression> >();
                }

                _lambdaParameters.Push(new Dictionary <string, ParameterExpression>()
                {
                    { lambdaExpression.Parameters.First(), Expression.Parameter(elementType) }
                });

                //Visit the lambda expression
                lambdaExpression.Accept(this);
                lambda = PopStack();

                if (!(lambda is System.Linq.Expressions.LambdaExpression expr) || expr.ReturnType != typeof(bool))
                {
                    throw new SqlErrorException("Lambda expression in 'first' must return a boolean.");
                }
            }

            var whereCall = ArrayFunctionUtils.CallFirstOrDefault(elementType, column, lambda);

            var nullableType = NullableUtils.ToNullable(whereCall.Type);

            if (nullableType != whereCall.Type)
            {
                whereCall = Expression.Convert(whereCall, nullableType);
            }

            var nullCheck = Expression.Condition(Expression.Equal(column, Expression.Constant(null, column.Type)), Expression.Constant(null, nullableType), whereCall);

            AddExpressionToStack(nullCheck);
        }