A where clause comparing a lazy loading proxy to a navigation property of a table is throwing an InvalidOperationException like the one below on .NET Core 3.0 and 3.1. This worked on .NET Core 2.1. While it's possible to work around this by replacing a particular instance with a key comparison, tracking down all of the instances in our project would be a lot of work.
The error also suggests that EF is trying to do a join instead of just comparing the proxy's primary key to the child table's foreign key.
The query is:
```C#
var eventTeams = await (from Team team in _context.Teams
where team.Event == myEvent // proxy fetched by a previous query
select team).ToListAsync();
The types involved are a simple parent-child relationship:
```C#
public class Event
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
// other columns
}
public class Team
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
// The event the team is a part of
public int EventID { get; set; }
// The event the team is a part of
[Required]
public virtual Event Event { get; set; }
// Other columns
}
The full exception is:
'The LINQ expression 'Where<TransparentIdentifier<Team, Event>>(
source: Join<Team, Event, Nullable<int>, TransparentIdentifier<Team, Event>>(
outer: Cast<Team>(DbSet<Team>),
inner: DbSet<Event>,
outerKeySelector: (e) => Property<Nullable<int>>(e, "EventID"),
innerKeySelector: (e0) => Property<Nullable<int>>(e0, "ID"),
resultSelector: (o, i) => new TransparentIdentifier<Team, Event>(
Outer = o,
Inner = i
)),
predicate: (e) => e.Inner == (Unhandled parameter: __myEvent_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 either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.'
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.<VisitMethodCall>g__CheckTranslated|8_0(ShapedQueryExpression translated, <>c__DisplayClass8_0& )
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
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__DisplayClass12_0`1.<ExecuteAsync>b__0()
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetAsyncEnumerator(CancellationToken cancellationToken)
at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable`1.GetAsyncEnumerator()
at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.<ToListAsync>d__64`1.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
EF Core version: 3.1
Database provider:Microsoft.EntityFrameworkCore.SqlServer
Target framework: 3.1
Operating system: Windows 10
IDE: Visual Studio 2019 16.4.3
It turns out this only repros if you put the type of the variable in the LINQ query, so this works:
var eventTeams = from team in _context.Teams
where team.Event == Event
select team;
But this doesn't
var eventTeams = from Team team in _context.Teams
where team.Event == Event
select team;
Calling query extension methods directly also works.
Given Event is an entityType, the where predicate in exception message should have been re-written into entity equality.
cc: @roji
We can add it to my pile of EE issues.
related #20164