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); }
protected override Expression VisitConditional(ConditionalExpression expression) { ArgumentUtility.CheckNotNull("expression", expression); return(SqlCaseExpression.CreateIfThenElse( expression.Type, Visit(expression.Test), Visit(expression.IfTrue), Visit(expression.IfFalse))); }
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); }
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)); }
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); }
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")); }
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?))); }
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))); } }
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); }
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)); }
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); }
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); }
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); }
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); }
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); }
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)); }