-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
QueryRewrite: support contains on collection navigation #15554
Comments
@maumar Why is the translation to |
@ajcvickers, @smitpatel I tried this to try to answer the question above, and a query like this throws before generating any SQL using nightly builds. Is this a known issue:
|
It should have been rewritten by #15939 Can you write PK based equality directly and see if it translates? |
@smitpatel yes, it does translate: SELECT CASE
WHEN @__someThing_Id_0 IN (
SELECT [t].[Id]
FROM [Things] AS [t]
WHERE ([p].[Id] = [t].[PersonId]) AND [t].[PersonId] IS NOT NULL
)
THEN CAST(1 AS bit)
ELSE CAST(0 AS bit)
END
FROM [People] AS [p] Repro: using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
namespace Repro15554
{
class Program
{
static void Main(string[] args)
{
using (var context = new MyContext())
{
context.Database.EnsureDeleted();
context.Database.EnsureCreated();
var someThing = new Thing { Id = 1 };
var query1 = context.People
.Select(p => p.Things.Contains(someThing))
.ToList(); // fails
var query2 = context.People
.Select(p => p.Things.Select(t => t.Id).Contains(someThing.Id))
.ToList(); // works
}
}
}
public class MyContext : DbContext
{
public DbSet<Person> People { get; set; }
public DbSet<Thing> Things { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseSqlServer(@"server=(localdb)\mssqllocaldb; database=parameternames; integrated security=true; connectretrycount=0")
.AddInterceptors(new LoggingInterceptor(Console.WriteLine));
}
}
public class Thing
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Thing> Things { get; set; } = new List<Thing>();
}
public class LoggingInterceptor : DbCommandInterceptor
{
private readonly Action<string> _loggingAction;
public LoggingInterceptor(Action<string> loggingAction)
{
_loggingAction = loggingAction;
}
public override InterceptionResult<DbDataReader> ReaderExecuting(DbCommand command, CommandEventData eventData, InterceptionResult<DbDataReader> result)
{
_loggingAction(command.CommandText);
return base.ReaderExecuting(command, eventData, result);
}
}
} |
So now the questions:
|
The translation looks correct to me 😄 |
Contains on keys seems correct to me also. I don't remember what I meant by my initial comment, perhaps we tried to create IN directly on entity objects, rather than keys. Either way, I agree with @smitpatel and @divega here |
EE handled the extension version of {IQueryable,IEnumerable}.Contains, but not instance methods such as List.Contains. Fixes #15554
EE handled the extension version of {IQueryable,IEnumerable}.Contains, but not instance methods such as List.Contains. Fixes #15554
EE handled the extension version of {IQueryable,IEnumerable}.Contains, but not instance methods such as List.Contains. Fixes #15554
EE handled the extension version of {IQueryable,IEnumerable}.Contains, but not instance methods such as List.Contains. Fixes #15554
EE handled the extension version of {IQueryable,IEnumerable}.Contains, but not instance methods such as List.Contains. Fixes #15554
EE handled the extension version of {IQueryable,IEnumerable}.Contains, but not instance methods such as List.Contains. Fixes #15554
EE handled the extension version of {IQueryable,IEnumerable}.Contains, but not instance methods such as List.Contains. Fixes #15554
EE handled the extension version of {IQueryable,IEnumerable}.Contains, but not instance methods such as List.Contains. Fixes #15554
EE handled the extension version of {IQueryable,IEnumerable}.Contains, but not instance methods such as List.Contains. Fixes #15554
EE handled the extension version of {IQueryable,IEnumerable}.Contains, but not instance methods such as List.Contains. Fixes #15554
EE handled the extension version of {IQueryable,IEnumerable}.Contains, but not instance methods such as List.Contains. Fixes #15554
EE handled the extension version of {IQueryable,IEnumerable}.Contains, but not instance methods such as List.Contains. Fixes #15554
query:
currently Enumerable.Contains is translated to
IN
, which is incorrect for the case aboveThe text was updated successfully, but these errors were encountered: