With the changes to .NET Core 3.0 I am getting
... NavigationExpandingExpressionVisitor' failed. This may indicate either a bug or a limitation in EF Core. See https://go.microsoft.com/fwlink/?linkid=2101433 for more detailed information.) ---> System.InvalidOperationException: Processing of the LINQ expression 'GroupJoin, ...
This is a really simple query so there must be a way to perform it in .NET CORE 3.0:
var queryResults1 = await patients .GroupJoin( _context.Studies, p => p.Id, s => s.Patient.Id, (p, studies) => new { p.DateOfBirth, p.Id, p.Name, p.Sex, Studies =studies.Select(s1=>s1) } ) .AsNoTracking().ToListAsync();
I am basically looking for a Linq query (or method syntax as above) which will join Studies onto Patients, and set Studies to an empty list or null if there are no studies for the given patient.
Any ideas? This was working in .NET Core 2.2. Also the MSFT link above mentions that the key breaking change is related to client side evaluation and avoiding that the generated query reads entire tables which must then be joined or filtered client side. However with this simple query, the join should be easily doable server side.
The LINQ join operator allows us to join multiple tables on one or more columns (multiple columns). By default, they perform the inner join of the tables. We also learn how to perform left joins in Entity Framework by using the join operator & DefaultIfEmpty method.
Entity Framework Joining In SQL, a JOIN clause is used to combine data from two or more tables, based on a related column between them. Similarly, in Entity Framework, the LINQ Join is used to load data from two or more tables.
The group join is useful for producing hierarchical data structures. It pairs each element from the first collection with a set of correlated elements from the second collection. For example, a class or a relational database table named Student might contain two fields: Id and Name .
As discussed here, you're attempting a query that isn't supported by the database. EF Core 2 used client-side evaluation to make your code work, but EF Core 3 refuses, because the client-side convenience comes at the cost of hard-to-debug performance problems as the dataset increases.
You can use use DefaultIfEmpty
to left join the patients' studies and then group manually with ToLookup
.
var query = from p in db.Patients join s in db.Studies on p.Id equals s.PatientId into studies from s in studies.DefaultIfEmpty() select new { Patient = p, Study = s }; var grouping = query.ToLookup(e => e.Patient); // Grouping done client side
The above example grabs the full Patient and Study entities, but you can cherry pick columns instead. If the data you need from Patient is too big to repeat for each Study, in the joined query select only the Patient ID, querying the rest of the Patient data in a separate non-joined query.
Had exactly the same issue and a big struggle with it. It turns out that .net Core 3.0 does not support Join or Groupjoin in method syntax (yet?). The fun part is though, it does work in Query syntax.
Try this, it's query syntax with a bit of method syntax. This translates nicely to the correct SQL query with a nice left outer join and it is processed on the database. I haven't got your models so you need to check the syntax yourselves....
var queryResults1 = (from p in _context.patients from s in _context.Studies.Where(st => st.PatientId == p.Id).DefaultIfEmpty() select new { p.DateOfBirth, p.Id, p.Name, p.Sex, Studies = studies.Select(s1 => s1) }).ToListAsync();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With