Fully support parameterized and inline lists of entity types in queries
- Dominant language
- C#
- Stars
- 14.8k
- Forks
- 3.4k
- PR merge metrics
- PR metrics pending
Description
Support the following:
```c#
List posts =
[
new() { Title = "First Post", Views = 100 },
new() { Title = "Second Post", Views = 250 }
];
// The following does a simple "entity equality contains", comparing keys
// (not that composite keys are not supported)
// WHERE [p].[Id] IN (@entity_equality_posts_Id1, @entity_equality_posts_Id2)
// _ = await context.Posts.Where(p => posts.Contains(p)).ToListAsync();
var q = await context.Posts
.Join(posts, p => p.Title, p => p.Title, (ur, cr) => ur)
.ToListAsync();
```
We could translate `posts` to a SQL VALUES expression containing parameters (or constants for inline collection instead of paramerized ones). Note that we do allow a such parameterized/inline collections for Contains only, translating to IN over a single key property (composite keys are not supported).
The VALUES translation would produce dynamic SQL (it would change based on the number of elements in the array). However, we already do that for Contains - this doesn't seem any different.
See similar issue but for complex types rather than for top-level entity types: #36468.
We also have various issues about supporting tuples in this context, e.g. #11799.
Full code sample
```c#
await using var context = new BlogContext();
await context.Database.EnsureDeletedAsync();
await context.Database.EnsureCreatedAsync();
List posts =
[
new() { Title = "First Post", Views = 100 },
new() { Title = "Second Post", Views = 250 }
];
// The following does a simple "entity equality contains", comparing keys
// (not that composite keys are not supported)
// WHERE [p].[Id] IN (@entity_equality_posts_Id1, @entity_equality_posts_Id2)
// _ = await context.Posts.Where(p => posts.Contains(p)).ToListAsync();
// Doesn't currently work.
var q = await context.Posts
.Join(posts, p => p.Title, p => p.Title, (ur, cr) => ur)
.ToListAsync();
public class BlogContext : DbContext
{
public DbSet Posts { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseSqlServer(Environment.GetEnvironmentVariable("Test__SqlServer__DefaultConnection"))
.LogTo(Console.WriteLine, LogLevel.Information)
.EnableSensitiveDataLogging();
}
public class Post
{
public int Id { get; set; }
public string Title { get; set; }
public int Views {get; set;}
}
```
Contributor guide
Assessment
This issue has not been assessed yet.