Allow parameterized types in queries using inheritance mapping (TPH, possibly even TPC/TPT)
- Dominant language
- C#
- Stars
- 14.8k
- Forks
- 3.4k
- PR merge metrics
- PR metrics pending
Description
Using a type variable in a `Where()` predicate to compare to `GetType()` fails to translate; only a hardcoded type using `typeof(...)` seems to be supported. Tested on both InMemory and SqlServer databases.
Repro
```C#
using Microsoft.EntityFrameworkCore;
namespace EfCoreExample {
internal class GetTypeExample {
public class Model {
public int Id { get; set; }
}
public class DataContext : DbContext {
public DbSet Models { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseInMemoryDatabase("example");
//options.UseSqlServer(connectionString: @"Data Source=(LocalDB)\MSSQLLocalDB;Initial Catalog=EfCoreExample;Integrated Security=True;MultipleActiveResultSets=true;Trusted_Connection=True;");
}
public static void Run() {
using var db = new DataContext();
db.Database.EnsureDeleted();
db.Database.EnsureCreated();
_ = db.Models
.Where(x => x.GetType() == typeof(Model)) // <-- works
.ToArray();
var type = typeof(Model);
_ = db.Models
.Where(x => x.GetType() == type) // <-- fails with "The LINQ expression 'DbSet().Where(m => m.GetType() == __type_0)' could not be translated"
.ToArray();
}
}
}
```
Results in
```
System.InvalidOperationException
HResult=0x80131509
Message=The LINQ expression 'DbSet()
.Where(m => m.GetType() == __type_0)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
Source=Microsoft.EntityFrameworkCore
StackTrace:
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.Translate(Expression expression)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutorExpression[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass11_0`1.b__0()
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteCore[TResult](Expression query, Boolean async, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetEnumerator()
at System.Collections.Generic.LargeArrayBuilder`1.AddRange(IEnumerable`1 items)
at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source)
at EfCoreExample.GetTypeExample.Run() in C:\Users\jhelm\dev\EfCoreExample\GetTypeExample.cs:line 31
at EfCoreExample.Program.Main(String[] args) in C:\Users\jhelm\dev\EfCoreExample\Program.cs:line 7
```
EF Core version: 8.0.11, 9.0.0
Database provider: Microsoft.EntityFrameworkCore.SqlServer, Microsoft.EntityFrameworkCore.InMemory
Target framework: .NET 8.0
Operating system: Microsoft Windows [Version 10.0.22635.4515]
IDE: Visual Studio 2022 17.11.6
Contributor guide
Assessment
This issue has not been assessed yet.