实体框架核心2.1在左联接上引发ArgumentException

时间:2018-06-27 14:39:10

标签: entity-framework asp.net-core .net-core entity-framework-core asp.net-core-2.0

我最近将项目从.NET Core 2.0升级到2.1。我使用Entity Framework Core,并具有几个包含左联接的LINQ表达式。以下代码是示例:

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();

如果是.NET Core 2.0,则此行无例外地执行。在.NET Core 2.1中,它引发以下ArgumentException:

  

System.ArgumentException:'字段   'Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor + TransparentIdentifier`2 [Microsoft.EntityFrameworkCore.Storage.ValueBuffer,System.Collections.Generic.IEnumerable`1 [Microsoft.EntityFrameworkCore.Storage.ValueBuffer]]。Inner'   没有为类型定义   'Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor + TransparentIdentifier`2 [Microsoft.EntityFrameworkCore.Storage.ValueBuffer,Microsoft.EntityFrameworkCore.Storage.ValueBuffer]''

如果我将LINQ更改为执行内部联接而不是左联接,则它不会执行任何问题。但是,该联接需要保留为左联接,所以我不能只更新所有代码来进行内部联接。

有人知道为什么执行左联接时EF Core 2.1现在会抛出ArgumentExecptions,以及如何解决该问题?

3 个答案:

答案 0 :(得分:2)

我不确定为什么要自己创建联接而不是使用EF关联模型。我以您的示例为例,对其进行了一些更改。

型号:

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; }
}

要定义外部联接,只需使外键为空即可。

像这样创建模型后,就可以在查询中包括属性:

Tickets = (from t in _dbContext.Tickets
              .Include(t => t.Member)
                  .ThenInclude(m => m.MemberType)
            select t).ToList();

生成的sql如下所示:

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]

希望能帮助您解决问题。

答案 1 :(得分:0)

通过工具>选项选中Enable Just My code

enter image description here

答案 2 :(得分:0)

对我来说,我在这里找到的最佳解决方案:[https://stackoverflow.com/a/58017017/1983909] 来自stackoverflow用户:HakanÇelikMK1


使用Visual Studio 2019(我也假定为2017),可以仅针对System.Linq.Expressions禁用此异常。

方法如下:

  • 打开“例外设置”窗口。调试-> Windows->例外设置(Ctrl + Alt + E)
  • 窗口右上方有一个搜索框,在其中键入“ System.ArgumentException”
  • 您将在窗口中看到例外,右键单击它,然后从菜单中选择“编辑条件”
  • 编辑条件允许您设置引发异常时调试器中断的条件
  • 从左至右,选择“模块名称”,选择“不等于”,然后在右侧的编辑框中键入“ System.Linq.Expressions.dll” 单击确定,然后关闭窗口