diff --git a/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs b/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs index 1d078d6..40c3351 100644 --- a/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs +++ b/src/EntityFramework6.Npgsql/SqlGenerators/SqlBaseGenerator.cs @@ -829,6 +829,23 @@ protected string GetDbType(EdmType edmType) public override VisitedExpression Visit([NotNull] DbCaseExpression expression) { + // Check for COALESCE like CASE + if (expression.When.Count == 1 && + expression.When[0].ExpressionKind == DbExpressionKind.IsNull) + { + var isNullExpression = expression.When[0] as DbIsNullExpression; + if (isNullExpression.Argument.Equals(expression.Else)) + { + LiteralExpression coalesceExpression = new LiteralExpression(" COALESCE( "); + coalesceExpression.Append(expression.Else.Accept(this)); + coalesceExpression.Append(","); + coalesceExpression.Append(expression.Then[0].Accept(this)); + coalesceExpression.Append(") "); + return coalesceExpression; + } + } + + // General CASE var caseExpression = new LiteralExpression(" CASE "); for (var i = 0; i < expression.When.Count && i < expression.Then.Count; ++i) { diff --git a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs index 1fbb22e..821cdf5 100644 --- a/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs +++ b/test/EntityFramework6.Npgsql.Tests/EntityFrameworkBasicTests.cs @@ -772,5 +772,67 @@ public void TestTableValuedStoredFunctions() Assert.AreEqual(1, list2[0].Something); } } + + [Test] + public void Test_issue_60_and_62() + { + using (var context = new BloggingContext(ConnectionString)) + { + context.Database.Log = Console.Out.WriteLine; + + context.Blogs.Add( new Blog { Name = "Hello" }); + context.SaveChanges(); + + string stringValue = "string_value"; + var query = context.Blogs.Select(b => stringValue + "_postfix"); + var blogTitle = query.First(); + Assert.That(blogTitle, Is.EqualTo("string_value_postfix")); + Console.WriteLine(query.ToString()); + StringAssert.AreEqualIgnoringCase("SELECT COALESCE( @p__linq__0,E'') || E'_postfix' AS \"C1\" FROM \"dbo\".\"Blogs\" AS \"Extent1\"", query.ToString()); + } + } + + [Test] + public void TestNullPropagation_1() + { + using (var context = new BloggingContext(ConnectionString)) + { + context.Database.Log = Console.Out.WriteLine; + + context.Blogs.Add( new Blog { Name = "Hello" }); + context.SaveChanges(); + + string stringValue = "string_value"; + var query = context.Blogs.Select(b => (stringValue ?? "default_value") + "_postfix"); + var blog_title = query.First(); + Assert.That(blog_title, Is.EqualTo("string_value_postfix")); + + Console.WriteLine(query.ToString()); + StringAssert.AreEqualIgnoringCase("SELECT CASE WHEN ( COALESCE( @p__linq__0,E'default_value') IS NULL) THEN (E'') WHEN (@p__linq__0 IS NULL) THEN (E'default_value') ELSE (@p__linq__0) END || E'_postfix' AS \"C1\" FROM \"dbo\".\"Blogs\" AS \"Extent1\"", query.ToString()); + } + } + + [Test] + public void TestNullPropagation_2() + { + using (var context = new BloggingContext(ConnectionString)) + { + context.Database.Log = Console.Out.WriteLine; + + context.Blogs.Add( new Blog { Name = "Hello" }); + context.SaveChanges(); + + string stringValue1 = "string_value1"; + string stringValue2 = "string_value2"; + string stringValue3 = "string_value3"; + + var query = context.Blogs.Select(b => (stringValue1 ?? stringValue2 ?? stringValue3) + "_postfix"); + var blog_title = query.First(); + Assert.That(blog_title, Is.EqualTo("string_value1_postfix")); + + Console.WriteLine(query.ToString()); + StringAssert.AreEqualIgnoringCase("SELECT CASE WHEN ( COALESCE( @p__linq__0, COALESCE( @p__linq__1,@p__linq__2) ) IS NULL) THEN (E'') WHEN (@p__linq__0 IS NULL) THEN ( COALESCE( @p__linq__1,@p__linq__2) ) ELSE (@p__linq__0) END || E'_postfix' AS \"C1\" FROM \"dbo\".\"Blogs\" AS \"Extent1\"", query.ToString()); + } + } } }