Describe what is not working as expected.
Some combilne lead to invalid sql or InvalidOperationException or ClientEvaluation.
Steps to reproduce
Include a complete code listing (or project/solution) that we can run to reproduce the issue.
Partial code listings, or multiple fragments of code, will slow down our response or cause us to push the issue back to you to provide code to reproduce the issue.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.0.0-preview.19074.3" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="2.2.0" />
</ItemGroup>
</Project>
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
namespace ConsoleApp15
{
internal static class Program
{
public static List<T> ToListCatched<T>(this IQueryable<T> query, ILogger logger)
{
try
{
return query.ToList();
}
catch (Exception ex)
{
logger?.LogError(ex.ToString());
return null;
}
}
private static void Main(string[] args)
{
using (var ctx = new TestContext())
{
var needInit = false;
try
{
needInit = !(ctx.Test001.Any() && ctx.Test002.Select(dx => true).FirstOrDefault());
}
catch
{
needInit = true;
}
if (needInit)
{
#region init data
ctx.Database.EnsureDeleted();
ctx.Database.EnsureCreated();
ctx.Test001.Add(new Test001() { GroupByKey = 1, OrderByKey = 1 });
ctx.Test001.Add(new Test001() { GroupByKey = 1, OrderByKey = 2 });
ctx.Test001.Add(new Test001() { GroupByKey = 1, OrderByKey = 1 });
ctx.Test001.Add(new Test001() { GroupByKey = 2, OrderByKey = 2 });
ctx.Test001.Add(new Test001() { GroupByKey = 2, OrderByKey = 1 });
ctx.Test001.Add(new Test001() { GroupByKey = 2, OrderByKey = 2 });
ctx.Test002.Add(new Test002() { PK1 = 1, PK2 = 1, GroupByKey = 1, OrderByKey = 1 });
ctx.Test002.Add(new Test002() { PK1 = 1, PK2 = 2, GroupByKey = 2, OrderByKey = 2 });
ctx.Test002.Add(new Test002() { PK1 = 1, PK2 = 3, GroupByKey = 1, OrderByKey = 1 });
ctx.Test002.Add(new Test002() { PK1 = 2, PK2 = 1, GroupByKey = 1, OrderByKey = 2 });
ctx.Test002.Add(new Test002() { PK1 = 2, PK2 = 2, GroupByKey = 2, OrderByKey = 1 });
ctx.Test002.Add(new Test002() { PK1 = 2, PK2 = 3, GroupByKey = 2, OrderByKey = 2 });
ctx.Test002.Add(new Test002() { PK1 = 3, PK2 = 1, GroupByKey = 2, OrderByKey = 2 });
ctx.Test002.Add(new Test002() { PK1 = 3, PK2 = 2, GroupByKey = 1, OrderByKey = 1 });
ctx.Test002.Add(new Test002() { PK1 = 3, PK2 = 3, GroupByKey = 2, OrderByKey = 2 });
ctx.SaveChanges();
#endregion
}
//use after first query
var loggerFactory = ctx.loggerFactory;
var logger = loggerFactory.CreateLogger("Main");
logger.LogInformation("-------------: begin");
logger.LogInformation("-------------: test .Take(2).Where(...).Select(_=>1).Any()");
Thread.Sleep(100);//Flush
//ClientEvaluation
logger.LogInformation("case_Any_Take1_Sel0: ");
var q1 = ctx.Test001.Where(d1 => ctx.Test001
.Select(d2 => new { PK = d2.PK })
.OrderBy(d2 => d2.PK)
.Take(2)
//d1.PK
.Where(d2 => d2.PK == 1)
//.Select(d2 => 1)
.Any())
.ToList();
Thread.Sleep(100);//Flush
//good
logger.LogInformation("case_Any_Take1_Sel1: ");
var q2 = ctx.Test001.Where(d1 => ctx.Test001
.Select(d2 => new { PK = d2.PK })
.OrderBy(d2 => d2.PK)
.Take(2)
//d1.PK
.Where(d2 => d2.PK == 1)
.Select(d2 => 1)
.Any())
.ToList();
Thread.Sleep(100);//Flush
//good
logger.LogInformation("case_Any_Take0_Sel0: ");
var q3 = ctx.Test001.Where(d1 => ctx.Test001
.Select(d2 => new { PK = d2.PK })
.OrderBy(d2 => d2.PK)
//.Take(2)
.Where(d2 => d2.PK == 1)
//.Select(d2 => 1)
.Any())
.ToList();
Thread.Sleep(100);//Flush
//broken since 2.1.0 with `d2.PK == 1`, not happen when change to `d2.PK == 1` or `d2.PK == d1.PK`
/*
SELECT [d1].[PK], [d1].[GroupByKey], [d1].[OrderByKey]
FROM [Test001] AS [d1]
WHERE [d2].[PK] IN (
SELECT 1
FROM [Test001] AS [d2]
)
*/
logger.LogInformation("case_Any_Take0_Sel1: ");
List<Test001> q4 = ctx.Test001.Where(d1 => ctx.Test001
.Select(d2 => new { PK = d2.PK })
.OrderBy(d2 => d2.PK)
//.Take(2)
.Where(d2 => d2.PK == 1)
.Select(d2 => 1)
.Any())
.ToListCatched(logger);
Thread.Sleep(100);//Flush
logger.LogInformation("-------------: test for .Take(2).Where(...).Select(_=>true).FirstOrDefault() with Test001");
Thread.Sleep(100);//Flush
logger.LogInformation("take0_select_true_first_key1: ");
//good
var f1 = ctx.Test001.Where(outer => ctx.Test001
.Where(inner => inner.GroupByKey == outer.GroupByKey)
.OrderBy(inner => inner.OrderByKey)
.Select(inner => new { inner.PK })
.Where(inner => inner.PK == outer.PK)
.Select(inner => true)
.FirstOrDefault()
)
.ToList();
Thread.Sleep(100);//Flush
logger.LogInformation("take1_select_true_first_key1: ");
//System.InvalidOperationException: No coercion operator is defined between types 'System.Int32' and 'System.Nullable`1[System.Boolean]'
var f2 = ctx.Test001.Where(outer => ctx.Test001
.Where(inner => inner.GroupByKey == outer.GroupByKey)
.OrderBy(inner => inner.OrderByKey)
.Select(inner => new { inner.PK })
.Take(2)
.Where(inner => inner.PK == outer.PK)
.Select(inner => true)
.FirstOrDefault()
)
.ToListCatched(logger);
Thread.Sleep(100);//Flush
logger.LogInformation("-------------: test for .Take(2).Where(...).Select(_=>true).FirstOrDefault() with Test002");
Thread.Sleep(100);//Flush
logger.LogInformation("take0_select_true_first_key2: ");
var f3 = ctx.Test002.Where(outer => ctx.Test002
.Where(inner => inner.GroupByKey == outer.GroupByKey)
.OrderBy(inner => inner.OrderByKey)
.Select(inner => new { inner.PK1, inner.PK2 })
//.Take(2)
.Where(inner => inner.PK1 == outer.PK1 && inner.PK2 == outer.PK2)
.Select(inner => true)
.FirstOrDefault()
)
.ToList();
Thread.Sleep(100);//Flush
logger.LogInformation("take1_select_true_first_key2: ");
//bad sql
/*
SELECT [outer].[PK1], [outer].[PK2], [outer].[GroupByKey], [outer].[OrderByKey]
FROM [Test002] AS [outer]
WHERE COALESCE((
SELECT TOP(1) [t].[PK1], [t].[PK2]
FROM (
SELECT TOP(2) [inner].[PK1], [inner].[PK2]
FROM [Test002] AS [inner]
WHERE [inner].[GroupByKey] = [outer].[GroupByKey]
ORDER BY [inner].[OrderByKey]
) AS [t]
WHERE ([t].[PK1] = [outer].[PK1]) AND ([t].[PK2] = [outer].[PK2])
), 0) = 1
*/
var f4 = ctx.Test002.Where(outer => ctx.Test002
.Where(inner => inner.GroupByKey == outer.GroupByKey)
.OrderBy(inner => inner.OrderByKey)
.Select(inner => new { inner.PK1, inner.PK2 })
.Take(2)
.Where(inner => inner.PK1 == outer.PK1 && inner.PK2 == outer.PK2)
.Select(inner => true)
.FirstOrDefault()
)
.ToListCatched(logger);
Thread.Sleep(100);//Flush
logger.LogInformation("-------------: end");
Thread.Sleep(100);//Flush
loggerFactory.Dispose();
return;
}
}
}
#region DbContext
public partial class TestContext : DbContext
{
public LoggerFactory loggerFactory;
public TestContext()
{
}
public TestContext(DbContextOptions<TestContext> options)
: base(options)
{
}
public virtual DbSet<Test001> Test001 { get; set; }
public virtual DbSet<Test002> Test002 { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
optionsBuilder.UseSqlServer("Server=(localdb)\\MSSQLLocalDB;Database=Test_Database001;Trusted_Connection=True;");
//optionsBuilder.ConfigureWarnings(warnings => warnings.Throw(Microsoft.EntityFrameworkCore.Diagnostics.RelationalEventId.QueryClientEvaluationWarning));
}
loggerFactory = new LoggerFactory();
#pragma warning disable CS0618
loggerFactory.AddConsole(LogLevel.Information);
#pragma warning restore CS0618
optionsBuilder.UseLoggerFactory(loggerFactory);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Test001>(entity =>
{
entity.HasKey(d => d.PK);
});
modelBuilder.Entity<Test002>(entity =>
{
entity.HasKey(d => new { d.PK1, d.PK2 });
});
}
}
public partial class Test002
{
public int PK1 { get; set; }
public int PK2 { get; set; }
public int GroupByKey { get; set; }
public int OrderByKey { get; set; }
}
public partial class Test001
{
public int PK { get; set; }
public int GroupByKey { get; set; }
public int OrderByKey { get; set; }
}
#endregion DbContext
}
Further technical details
EF Core version: up to 3.0.0-preview.19074.3(case_Any_Take0_Sel1 used to work in 2.0.x, and the other 3 (take1_select_true_first_key1/take1_select_true_first_key2/case_Any_Take1_Sel0) always not work since 2.0.0)
Database Provider: Microsoft.EntityFrameworkCore.SqlServer
Operating system: not affected
IDE: not affected
Describe what is not working as expected.
Some combilne lead to invalid sql or InvalidOperationException or ClientEvaluation.
Steps to reproduce
Include a complete code listing (or project/solution) that we can run to reproduce the issue.
Partial code listings, or multiple fragments of code, will slow down our response or cause us to push the issue back to you to provide code to reproduce the issue.
Further technical details
EF Core version: up to 3.0.0-preview.19074.3(case_Any_Take0_Sel1 used to work in 2.0.x, and the other 3 (take1_select_true_first_key1/take1_select_true_first_key2/case_Any_Take1_Sel0) always not work since 2.0.0)
Database Provider: Microsoft.EntityFrameworkCore.SqlServer
Operating system: not affected
IDE: not affected