コード例 #1
0
        public void VisitMemberExpression_WithInnerSqlCaseExpression()
        {
            var testPredicate1 = Expression.Constant(true);
            var testPredicate2 = Expression.Constant(false);
            var value1         = Expression.Constant(new TypeWithMember <int> (1));
            var value2         = Expression.Constant(new TypeWithMember <int> (2));
            var elseValue      = Expression.Constant(new TypeWithMember <int> (3));

            var caseExpression = new SqlCaseExpression(
                typeof(TypeWithMember <int>),
                new[] { new SqlCaseExpression.CaseWhenPair(testPredicate1, value1), new SqlCaseExpression.CaseWhenPair(testPredicate2, value2) },
                elseValue);
            var memberExpression = Expression.Property(caseExpression, "Property");

            var result = SqlPreparationExpressionVisitor.TranslateExpression(memberExpression, _context, _stageMock, _methodCallTransformerProvider);

            var expectedResult = new SqlCaseExpression(
                typeof(int),
                new[]
            {
                new SqlCaseExpression.CaseWhenPair(testPredicate1, Expression.Property(value1, "Property")),
                new SqlCaseExpression.CaseWhenPair(testPredicate2, Expression.Property(value2, "Property"))
            },
                Expression.Property(elseValue, "Property"));

            SqlExpressionTreeComparer.CheckAreEqualTrees(expectedResult, result);
        }
コード例 #2
0
        protected override Expression VisitConditional(ConditionalExpression expression)
        {
            ArgumentUtility.CheckNotNull("expression", expression);

            return(SqlCaseExpression.CreateIfThenElse(
                       expression.Type, Visit(expression.Test), Visit(expression.IfTrue), Visit(expression.IfFalse)));
        }
コード例 #3
0
        public Expression ResolveIDPropertyViaForeignKey(SqlEntityExpression originatingEntity, RelationEndPointDefinition foreignKeyEndPoint)
        {
            ArgumentUtility.CheckNotNull("originatingEntity", originatingEntity);
            ArgumentUtility.CheckNotNull("foreignKeyEndPoint", foreignKeyEndPoint);

            var foreignKeyStorageProperty = _rdbmsPersistenceModelProvider.GetStoragePropertyDefinition(foreignKeyEndPoint.PropertyDefinition);

            var fullObjectIDStoragePropertyDefinition = foreignKeyStorageProperty as ObjectIDStoragePropertyDefinition;

            if (fullObjectIDStoragePropertyDefinition != null)
            {
                var classIDExpression = ResolveStorageProperty(originatingEntity, fullObjectIDStoragePropertyDefinition.ClassIDProperty);
                var valueExpression   = ResolveStorageProperty(originatingEntity, fullObjectIDStoragePropertyDefinition.ValueProperty);
                return(CreateCompoundObjectIDExpression(classIDExpression, valueExpression));
            }

            var objectIDWithoutClassIDStoragePropertyDefinition = foreignKeyStorageProperty as ObjectIDWithoutClassIDStoragePropertyDefinition;

            if (objectIDWithoutClassIDStoragePropertyDefinition != null)
            {
                // If the foreign key has no ClassID because the related object's class is always the same one, we still need to provide a full ObjectID,
                // including ClassID; otherwise, access to the ClassID property wouldn't work later on. (I.e., where o.Customer.ID.ClassID == ...)
                // We'll therefore use a literal as the ClassID. However, if the value property is null, we must also make the ClassID null.
                var valueExpression   = ResolveStorageProperty(originatingEntity, objectIDWithoutClassIDStoragePropertyDefinition.ValueProperty);
                var classIDExpression = SqlCaseExpression.CreateIfThenElse(
                    typeof(string),
                    new SqlIsNotNullExpression(valueExpression),
                    new SqlLiteralExpression(objectIDWithoutClassIDStoragePropertyDefinition.ClassDefinition.ID),
                    Expression.Constant(null, typeof(string)));
                return(CreateCompoundObjectIDExpression(classIDExpression, valueExpression));
            }

            return(null);
        }
コード例 #4
0
        public void CreateIfThenElse()
        {
            var result = SqlCaseExpression.CreateIfThenElse(typeof(int), _predicate1, _value1, _value2);

            Assert.That(result.Cases, Has.Count.EqualTo(1));
            Assert.That(result.Cases[0].When, Is.SameAs(_predicate1));
            Assert.That(result.Cases[0].Then, Is.SameAs(_value1));
            Assert.That(result.ElseCase, Is.SameAs(_value2));
        }
コード例 #5
0
        private MemberExpression CreateMemberExpressionWithInnerSqlCaseExpression <TMemberType> (Expression when, Expression then, Expression elseCase)
        {
            var valueTypeCaseExpression = new SqlCaseExpression(
                typeof(TypeWithMember <TMemberType>),
                new[] { new SqlCaseExpression.CaseWhenPair(when, then) },
                elseCase);
            var valueTypeMemberExpression = Expression.Property(valueTypeCaseExpression, "Property");

            return(valueTypeMemberExpression);
        }
コード例 #6
0
        public void VisitSqlCaseExpression_NoElse()
        {
            var case1      = new SqlCaseExpression.CaseWhenPair(new SqlCustomTextExpression("test1", typeof(bool)), new SqlCustomTextExpression("value1", typeof(int)));
            var case2      = new SqlCaseExpression.CaseWhenPair(new SqlCustomTextExpression("test2", typeof(bool)), new SqlCustomTextExpression("value2", typeof(int)));
            var expression = new SqlCaseExpression(typeof(int?), new[] { case1, case2 }, null);

            SqlGeneratingExpressionVisitor.GenerateSql(expression, _commandBuilder, _stageMock);

            Assert.That(_commandBuilder.GetCommandText(), Is.EqualTo("CASE WHEN test1 THEN value1 WHEN test2 THEN value2 END"));
        }
コード例 #7
0
        public void CreateIfThenElseNull()
        {
            var result = SqlCaseExpression.CreateIfThenElseNull(typeof(int?), _predicate1, _value1, _value2);

            Assert.That(result.Cases, Has.Count.EqualTo(2));
            Assert.That(result.Cases[0].When, Is.SameAs(_predicate1));
            Assert.That(result.Cases[0].Then, Is.SameAs(_value1));
            SqlExpressionTreeComparer.CheckAreEqualTrees(result.Cases[1].When, Expression.Not(_predicate1));
            Assert.That(result.Cases[1].Then, Is.SameAs(_value2));
            SqlExpressionTreeComparer.CheckAreEqualTrees(result.ElseCase, Expression.Constant(null, typeof(int?)));
        }
コード例 #8
0
 private Expression CreateValueExpressionForPredicate(Expression predicate)
 {
     // If the predicate is nullable, we have three cases (true, false, null). Otherweise, we just have two cases.
     if (predicate.Type == typeof(bool?))
     {
         return(SqlCaseExpression.CreateIfThenElseNull(typeof(int?), predicate, new SqlLiteralExpression(1), new SqlLiteralExpression(0)));
     }
     else
     {
         return(SqlCaseExpression.CreateIfThenElse(typeof(int), predicate, new SqlLiteralExpression(1), new SqlLiteralExpression(0)));
     }
 }
コード例 #9
0
        public void VisitBinaryExpression_WithConditionalExpressionInBinaryExpression()
        {
            var leftExpression    = Expression.Constant("Name");
            var testPredicate     = Expression.Constant(true);
            var ifTrueExpression  = Expression.Constant("true");
            var ifFalseExpression = Expression.Constant("false");
            var rightExpression   = Expression.Condition(testPredicate, ifTrueExpression, ifFalseExpression);
            var binaryExpression  = Expression.Equal(leftExpression, rightExpression);

            var result = SqlPreparationExpressionVisitor.TranslateExpression(binaryExpression, _context, _stageMock, _methodCallTransformerProvider);

            var expectedResult = Expression.Equal(
                leftExpression, SqlCaseExpression.CreateIfThenElse(typeof(string), testPredicate, ifTrueExpression, ifFalseExpression));

            SqlExpressionTreeComparer.CheckAreEqualTrees(expectedResult, result);
        }
コード例 #10
0
        public Expression VisitSqlCase(SqlCaseExpression expression)
        {
            ArgumentUtility.CheckNotNull("expression", expression);

            var newCases = Visit(
                expression.Cases,
                caseWhenPair =>
            {
                var newWhen = ApplyPredicateContext(caseWhenPair.When);
                var newThen = ApplySingleValueContext(caseWhenPair.Then);
                return(caseWhenPair.Update(newWhen, newThen));
            });
            var newElseCase = expression.ElseCase != null?ApplySingleValueContext(expression.ElseCase) : null;

            return(expression.Update(newCases, newElseCase));
        }
コード例 #11
0
        public void VisitMemberExpression_WithInnerCoalesceExpression_RevisitsResult()
        {
            var left  = Expression.Constant("left");
            var right = Expression.Constant("right");
            var coalesceExpression = Expression.Coalesce(left, right);
            var memberExpression   = Expression.Property(coalesceExpression, "Length");

            var result = SqlPreparationExpressionVisitor.TranslateExpression(memberExpression, _context, _stageMock, _methodCallTransformerProvider);

            var expectedResult = SqlCaseExpression.CreateIfThenElse(
                typeof(int),
                new SqlIsNotNullExpression(coalesceExpression.Left),
                new SqlLengthExpression(coalesceExpression.Left),
                new SqlLengthExpression(coalesceExpression.Right));

            SqlExpressionTreeComparer.CheckAreEqualTrees(expectedResult, result);
        }
コード例 #12
0
        public void VisitMemberExpression_WithInnerSqlCaseExpression_RevisitsResult()
        {
            var predicate = Expression.Constant(true);
            var value     = Expression.Constant("value1");
            var elseValue = Expression.Constant("value2");

            var caseExpression   = new SqlCaseExpression(typeof(string), new[] { new SqlCaseExpression.CaseWhenPair(predicate, value) }, elseValue);
            var memberExpression = Expression.Property(caseExpression, "Length");

            var result = SqlPreparationExpressionVisitor.TranslateExpression(memberExpression, _context, _stageMock, _methodCallTransformerProvider);

            var expectedResult = new SqlCaseExpression(
                typeof(int),
                new[] { new SqlCaseExpression.CaseWhenPair(predicate, new SqlLengthExpression(value)) },
                new SqlLengthExpression(elseValue));

            SqlExpressionTreeComparer.CheckAreEqualTrees(expectedResult, result);
        }
コード例 #13
0
        public void SetUp()
        {
            _predicate1     = Expression.Constant(true);
            _predicate2     = Expression.Constant(false, typeof(bool?));
            _value1         = Expression.Constant(17);
            _value2         = Expression.Constant(4);
            _nullableValue1 = Expression.Constant(47, typeof(int?));
            _elseValue      = Expression.Constant(42);

            _caseExpressionWithElse = new SqlCaseExpression(
                typeof(int),
                new[] { new SqlCaseExpression.CaseWhenPair(_predicate1, _value1), new SqlCaseExpression.CaseWhenPair(_predicate2, _value2) },
                _elseValue);
            _caseExpressionWithoutElse = new SqlCaseExpression(
                typeof(int?),
                new[] { new SqlCaseExpression.CaseWhenPair(_predicate1, _nullableValue1), new SqlCaseExpression.CaseWhenPair(_predicate2, _value2) },
                null);
        }
コード例 #14
0
        public Expression VisitSqlCaseExpression(SqlCaseExpression expression)
        {
            ArgumentUtility.CheckNotNull("expression", expression);

            _commandBuilder.Append("CASE");

            foreach (var caseWhenPair in expression.Cases)
            {
                _commandBuilder.Append(" WHEN ");
                VisitExpression(caseWhenPair.When);
                _commandBuilder.Append(" THEN ");
                VisitExpression(caseWhenPair.Then);
            }

            if (expression.ElseCase != null)
            {
                _commandBuilder.Append(" ELSE ");
                VisitExpression(expression.ElseCase);
            }
            _commandBuilder.Append(" END");
            return(expression);
        }
コード例 #15
0
        public void ResolveIDPropertyViaForeignKey_WithObjectIDWithoutClassID_ResolvesToCompoundWithFixedConditionalClassID()
        {
            var propertyDefinition      = CreatePropertyDefinitionAndAssociateWithClass(_classDefinition, "Customer", "Customer");
            var objectIDStorageProperty =
                new ObjectIDWithoutClassIDStoragePropertyDefinition(
                    SimpleStoragePropertyDefinitionObjectMother.CreateGuidStorageProperty("CustomerID"),
                    GetTypeDefinition(typeof(Customer)));

            var foreignKeyEndPointDefinition = new RelationEndPointDefinition(propertyDefinition, false);

            _rdbmsPersistenceModelProviderStub
            .Stub(stub => stub.GetStoragePropertyDefinition(foreignKeyEndPointDefinition.PropertyDefinition))
            .Return(objectIDStorageProperty);

            var originatingEntity = CreateEntityDefinition(typeof(Order), "o");

            var result = _storageSpecificExpressionResolver.ResolveIDPropertyViaForeignKey(originatingEntity, foreignKeyEndPointDefinition);

            var expectedValueColumn = originatingEntity.GetColumn(typeof(Guid), "CustomerID", false);
            var expected            = Expression.New(
                MemberInfoFromExpressionUtility.GetConstructor(() => new ObjectID("classID", "value")),
                new Expression[]
            {
                new NamedExpression(
                    "ClassID",
                    SqlCaseExpression.CreateIfThenElse(
                        typeof(string),
                        new SqlIsNotNullExpression(expectedValueColumn),
                        new SqlLiteralExpression("Customer"),
                        Expression.Constant(null, typeof(string)))),
                new NamedExpression("Value", Expression.Convert(expectedValueColumn, typeof(object)))
            },
                new[] { typeof(ObjectID).GetProperty("ClassID"), typeof(ObjectID).GetProperty("Value") });

            SqlExpressionTreeComparer.CheckAreEqualTrees(expected, result);
        }
コード例 #16
0
        protected override Expression VisitMember(MemberExpression expression)
        {
            ArgumentUtility.CheckNotNull("expression", expression);

            var newInnerExpression = Visit(expression.Expression);

            var innerExpressionAsSqlCaseExpression = newInnerExpression as SqlCaseExpression;

            if (innerExpressionAsSqlCaseExpression != null)
            {
                var originalCases    = innerExpressionAsSqlCaseExpression.Cases;
                var originalElseCase = innerExpressionAsSqlCaseExpression.ElseCase;
                var newCases         = originalCases.Select(c => new SqlCaseExpression.CaseWhenPair(c.When, Expression.MakeMemberAccess(c.Then, expression.Member)));
                var newElseCase      = originalElseCase != null?Expression.MakeMemberAccess(originalElseCase, expression.Member) : null;

                // If there is no else case, ensure that the resulting type is nullable
                var caseExpressionType =
                    newElseCase == null && expression.Type.IsValueType && Nullable.GetUnderlyingType(expression.Type) == null
                ? typeof(Nullable <>).MakeGenericType(expression.Type)
                : expression.Type;
                var newSqlCaseExpression = new SqlCaseExpression(caseExpressionType, newCases, newElseCase);
                return(Visit(newSqlCaseExpression));
            }

            if (newInnerExpression.NodeType == ExpressionType.Coalesce)
            {
                var innerExpressionAsBinaryExpression = (BinaryExpression)newInnerExpression;
                var newConditionalExpression          = Expression.Condition(
                    new SqlIsNotNullExpression(innerExpressionAsBinaryExpression.Left),
                    Expression.MakeMemberAccess(innerExpressionAsBinaryExpression.Left, expression.Member),
                    Expression.MakeMemberAccess(innerExpressionAsBinaryExpression.Right, expression.Member));
                return(Visit(newConditionalExpression));
            }

            var innerExpressionAsSqlSubStatementExpression = newInnerExpression as SqlSubStatementExpression;

            if (innerExpressionAsSqlSubStatementExpression != null)
            {
                var sqlStatementBuilder = new SqlStatementBuilder(innerExpressionAsSqlSubStatementExpression.SqlStatement);
                var namedExpression     = (NamedExpression)sqlStatementBuilder.SelectProjection;
                sqlStatementBuilder.SelectProjection = new NamedExpression(
                    namedExpression.Name, Visit(Expression.MakeMemberAccess(namedExpression.Expression, expression.Member)));
                sqlStatementBuilder.RecalculateDataInfo(innerExpressionAsSqlSubStatementExpression.SqlStatement.SelectProjection);
                return(new SqlSubStatementExpression(sqlStatementBuilder.GetSqlStatement()));
            }

            var memberAsPropertyInfo = expression.Member as PropertyInfo;

            if (memberAsPropertyInfo != null)
            {
                var methodInfo = memberAsPropertyInfo.GetGetMethod();
                if (methodInfo != null)
                {
                    var methodCallExpression = Expression.Call(expression.Expression, methodInfo);
                    var tranformer           = _methodCallTransformerProvider.GetTransformer(methodCallExpression);
                    if (tranformer != null)
                    {
                        var tranformedExpression = tranformer.Transform(methodCallExpression);
                        return(Visit(tranformedExpression));
                    }
                }
            }
            return(base.VisitMember(expression));
        }