Entity Framework Core 2.1 throwing ArgumentException on left join

.net-core asp.net-core asp.net-core-2.0 entity-framework entity-framework-core

Question

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?

1
5
6/27/2018 4:05:33 PM

Accepted Answer

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.

2
6/30/2018 12:09:37 PM

Popular Answer

From tools > Options check Enable Just My code

enter image description here



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow