Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework Core 2.1 throwing ArgumentException on left join

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?

like image 341
Courier Avatar asked Jun 27 '18 14:06

Courier


2 Answers

From tools > Options check Enable Just My code

enter image description here

like image 164
Mohammad Hossein Amri Avatar answered Nov 07 '22 00:11

Mohammad Hossein Amri


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.

like image 2
niQu Avatar answered Nov 07 '22 01:11

niQu