Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ternary expression and let with external boolean variable with false value produces invalid SQL. #9247

Closed
dmitryshunkov opened this issue Jul 23, 2017 · 2 comments
Assignees
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-bug
Milestone

Comments

@dmitryshunkov
Copy link

dmitryshunkov commented Jul 23, 2017

Let operator with expression that evaluates to false due to external argument in combination with conditional operator produces wrong SQL.

SELECT CASE
    WHEN 0
    THEN 1 ELSE 0
END
FROM [Posts] AS [post]
Exception message: An expression of non-boolean type specified in a context where a condition is expected, near 'THEN'.
Stack trace: at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
   at System.Data.SqlClient.SqlDataReader.get_MetaData()
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior)
   at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection connection, String executeMethod, IReadOnlyDictionary`2 parameterValues, Boolean closeConnection)
   at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteReader(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable.Enumerator.BufferlessMoveNext(Boolean buffer)
   at Microsoft.EntityFrameworkCore.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](Func`2 operation, Func`2 verifySucceeded, TState state)
   at Microsoft.EntityFrameworkCore.Query.QueryMethodProvider.<_ShapedQuery>d__3`1.MoveNext()
   at System.Linq.Enumerable.SelectEnumerableIterator`2.MoveNext()
   at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at TestEF.Program.Main() in C:\Git\Study\TestEF\TestEF\Program.cs:line 70
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace TestEF
{
    public class BloggingContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            ILoggerFactory loggerFactory = new LoggerFactory()
                .AddDebug();

            //optionsBuilder.UseInMemoryDatabase();
            optionsBuilder.EnableSensitiveDataLogging();
            optionsBuilder.UseLoggerFactory(loggerFactory);
            optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=WonkyVB;Trusted_Connection=True;");
        }
    }

    public class Blog
    {
        public int Id { get; set; }
        public string Title { get; set; }

        public ICollection<Post> Posts { get; set; }
    }

    public class Post
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public DateTime DateTime { get; set; }

        public int? BlogId { get; set; }
        public Blog Blog { get; set; }
    }

    public class PostDTO
    {
        public DateTime DateTime { get; set; }
        public string Title { get; set; }
    }

    public class Program
    {
        public static void Main()
        {
            using (var context = new BloggingContext())
            {
                context.Database.EnsureDeleted();
                context.Database.EnsureCreated();

                context.Add(new Blog
                {
                    Posts = new List<Post> { new Post { Title = "First" }, new Post { Title = "Second" }, new Post { Title = "Third" } }
                });
                context.SaveChanges();
            }

            using (var context = new BloggingContext())
            {
                bool externalCondition = false;

                var list = (from post in context.Posts
                           //let projectedExternalCondition = externalCondition                         // works
                           //let flag = post.Title == "some title" && projectedExternalCondition        // works
                           let flag = post.Title == "some title" && externalCondition                   // fails
                           select new
                           {
                               result = flag ? 1 : 0
                           }).ToList();

                foreach (var post in list)
                {
                    Console.WriteLine(post.result);
                }
            }
        }
    }
}

Further technical details

EF Core version: 1.1.2
Database Provider: Microsoft.EntityFrameworkCore.SqlServer
Operating system: Windows 10
IDE: Visual Studio 2017

@dmitryshunkov
Copy link
Author

Seems to be fixed in 2.0.0-preview2-final.

@smitpatel
Copy link
Contributor

Fixed via #7554

@smitpatel smitpatel added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Jul 24, 2017
@smitpatel smitpatel added this to the 2.0.0-preview1 milestone Jul 24, 2017
@smitpatel smitpatel self-assigned this Jul 24, 2017
@ajcvickers ajcvickers modified the milestones: 2.0.0-preview1, 2.0.0 Oct 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-bug
Projects
None yet
Development

No branches or pull requests

3 participants