question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Calling .AsQueryable() on List navigation properties with subqueries generates invalid SQL

See original GitHub issue

Steps to reproduce

GitHub repo: https://github.com/JulianKlauser/EF.Core.Subqueries (adjust connection string to local db).

The issue

Subqueries on navigation properties currently do not work as expected. If an .AsQueryable() is called on a List navigation property an exception is thrown (the generated SQL is not valid for the MySql Server).

This works:

context.Set<ParentEntity>()   
   .Where(parent => parent.ChildEntities
   .Any(child => child.Value =="Dummy")).ToList();

This does not:

context.Set<ParentEntity>()
   .Where(parent => parent.ChildEntities.AsQueryable()
   .Any(child => child.Value == "Dummy")).ToList();

The exception:

MySql.Data.MySqlClient.MySqlException
  HResult=0x80004005
  Message=Unknown column 'parent.Id' in 'where clause'
  Source=MySqlConnector
  StackTrace:
   at MySql.Data.MySqlClient.MySqlDataReader.ActivateResultSet(ResultSet resultSet) in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlDataReader.cs:line 98
   at MySql.Data.MySqlClient.MySqlDataReader.<ReadFirstResultSetAsync>d__94.MoveNext() in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlDataReader.cs:line 307
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at MySql.Data.MySqlClient.MySqlDataReader.<CreateAsync>d__93.MoveNext() in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlDataReader.cs:line 292
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at MySqlConnector.Core.TextCommandExecutor.<ExecuteReaderAsync>d__1.MoveNext() in C:\projects\mysqlconnector\src\MySqlConnector\Core\TextCommandExecutor.cs:line 37
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at MySql.Data.MySqlClient.MySqlCommand.ExecuteDbDataReader(CommandBehavior behavior) in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlCommand.cs:line 267
   at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection connection, DbCommandMethod executeMethod, IReadOnlyDictionary`2 parameterValues)
   at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteReader(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.BufferlessMoveNext(DbContext _, Boolean buffer)
   at Pomelo.EntityFrameworkCore.MySql.Storage.Internal.MySqlExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable`1.Enumerator.MoveNext()
   at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.<_TrackEntities>d__17`2.MoveNext()
   at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext()
   at System.Collections.Generic.List`1.AddEnumerable(IEnumerable`1 enumerable)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at EF.Core.Subqueries.Program.Main(String[] args) in D:\Git\EF.Core.Subqueries\EF.Core.Subqueries\Program.cs:line 22

Inner Exception 1:
MySqlException: Unknown column 'parent.Id' in 'where clause'

This is the generated (invalid) SQL from the logger:

SELECT `parent`.`Id`, `parent`.`Value`
      FROM `parent` AS `parent`
      WHERE EXISTS (
           SELECT 1
           FROM (
               SELECT `c`.`Id`, `c`.`ParentEntityId`, `c`.`Value`
               FROM `child` AS `c`
               WHERE `parent`.`Id` = `c`.`ParentEntityId`
          ) AS `t`
          WHERE `t`.`Value` = 'Dummy')

The reason why we need the .AsQueryable() is that we want to build the child expression dynamically and pass it in as a Expression<Func<ChildEntity,bool>>.

Further technical details

MySQL version: MariaDB 10.2.17 (also tried on MariaDB 10.3.7) Operating system: Windows 10 Pro (version 1809) Pomelo.EntityFrameworkCore.MySql version: v2.2.0 Microsoft.AspNetCore.App version: v2.2.0

Other details about my project setup: Using MariaDb instead of MySql.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:1
  • Comments:7 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
smitpatelcommented, Mar 13, 2019

To fix “derived table” limitation, it would require special casing in MySQL provider since it is database specific limitation. For the behavioral difference in both queries simply because of AsQueryable is due to Relinq. Relinq treats AsQueryable as result operator and causes a subquery. This should go away in 3.0 and if the query without AsQueryable is working then it would work with it too.

0reactions
JulianKlausercommented, Mar 14, 2019

I see. Thank you for the insightful comments, I have a better grasp of what is happening. We’ll wait for 3.0 then.

Read more comments on GitHub >

github_iconTop Results From Across the Web

EF Core - Unable to access navigation properties in Select()
with the following error: System.InvalidOperationException: The type of navigation property 'Roles' on the entity type 'IdentityUser<string, ...
Read more >
Don't use Linq's Join. Navigate! | Passion for Coding
In LINQ to SQL it's done through the LoadOptions property on the data context. In EF it's done by a call to Include()...
Read more >
Performance considerations for EF4, EF5, and EF6
The query plan cache is shared for all query types: Entity SQL, LINQ to Entities, and CompiledQuery objects. By default, query plan caching...
Read more >
Querying in Entity Framework Core
EF Core has a new feature in LINQ-to-Entities where we can include C# or VB.NET functions in the query. This was not possible...
Read more >
c# - Storing a temporary data outside of DbContext in Entity ...
I want my ORM to be a way to think in SQL while writing in C#, but navigation properties seem specifically designed to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found