I recently upgraded my project from .NET Core 2.0 to 2.1. I use Entity Framework Core and have several LINQ expressions that include left joins. The following code is an example:
var tickets = (from ticket in dbContext.Tickets
join member in dbContext.Members on ticket.MemberID equals member.ID into memberLEFT
from member in memberLEFT.DefaultIfEmpty()
join memberType in dbContext.MemberTypes on member.MemberTypeID equals memberType.ID into memberTypeLEFT
from memberType in memberTypeLEFT.DefaultIfEmpty()
select memberType)
.ToList();
If .NET Core 2.0, this line executed with no exceptions. In .NET Core 2.1, it's throwing the following ArgumentException:
System.ArgumentException: 'Field 'Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor+TransparentIdentifier`2[Microsoft.EntityFrameworkCore.Storage.ValueBuffer,System.Collections.Generic.IEnumerable`1[Microsoft.EntityFrameworkCore.Storage.ValueBuffer]].Inner' is not defined for type 'Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor+TransparentIdentifier`2[Microsoft.EntityFrameworkCore.Storage.ValueBuffer,Microsoft.EntityFrameworkCore.Storage.ValueBuffer]''
If I change the LINQ to perform inner joins instead of left, then it executes no problem. The joins need to be left joins though, so I can't just update all of my code to do inner joins.
Does anyone know why EF Core 2.1 is now throwing ArgumentExecptions when performing left joins, and how to get around the issue?
From tools > Options check Enable Just My code
I'm not sure why you creating your joins on your own instead of using the EF releationship model. I've taken your example and changed it a little bit.
Models:
public class Ticket
{
[Key]
public int ID { get; set; }
[Required]
[StringLength(200)]
public string Description { get; set; }
public int? MemberID { get; set; }
[ForeignKey(nameof(MemberID))]
public Member Member { get; set; }
}
public class Member
{
[Key]
public int ID { get; set; }
[Required]
[StringLength(200)]
public string Description { get; set; }
public int? MemberTypeID { get; set; }
public ICollection<Ticket> Tickets { get; set; }
[ForeignKey(nameof(MemberTypeID))]
public MemberType MemberType { get; set; }
}
public class MemberType
{
[Key]
public int ID { get; set; }
[Required]
[StringLength(200)]
public string Description { get; set; }
}
To define an outer join just make the foreign-key nullable.
When you've created your models like this you can just include the properties in your query:
Tickets = (from t in _dbContext.Tickets
.Include(t => t.Member)
.ThenInclude(m => m.MemberType)
select t).ToList();
The generated sql looks like this:
SELECT [t].[ID], [t].[Description], [t].[MemberID], [t.Member].[ID], [t.Member].
[Description], [t.Member].[MemberTypeID], [t.Member.MemberType].[ID],
[t.Member.MemberType].[Description]
FROM [Tickets] AS [t]
LEFT JOIN [Members] AS [t.Member] ON [t].[MemberID] = [t.Member].[ID]
LEFT JOIN [MemberTypes] AS [t.Member.MemberType] ON [t.Member].[MemberTypeID] =
[t.Member.MemberType].[ID]
Hope that helps your issue.
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