Entity Framework Core 2.1 создает исключение ArgumentException при левом соединении - PullRequest
0 голосов
/ 27 июня 2018

Я недавно обновил свой проект с .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 для выполнения внутренних объединений вместо left, то это не вызовет проблем. Тем не менее, объединения должны быть оставлены, поэтому я не могу просто обновить весь свой код для выполнения внутренних объединений.

Кто-нибудь знает, почему EF Core 2.1 теперь генерирует ArgumentExecptions при выполнении левых соединений, и как обойти эту проблему?

Ответы [ 2 ]

0 голосов
/ 31 мая 2019

Из Инструменты> Параметры Проверка Enable Just My code

enter image description here

0 голосов
/ 30 июня 2018

Я не уверен, почему вы создаете свои объединения самостоятельно, а не используете модель выпуска 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]

Надеюсь, это поможет вашей проблеме.

...