Неправильный запрос сгенерированный с EF Core 3.0 - PullRequest
1 голос
/ 11 ноября 2019

Я пытаюсь использовать простое предложение where для извлечения данных из SQL Server. Однако сгенерированный запрос неверен. Этот запрос отлично работал с EF Core 2.2, но с EF Core 3 он выдает исключение.

    public async Task<List<CharacterReplacements>> GetReplacementsAsync(int? replacementSetId)
    {
        var replacementQuery = _context.CharacterReplacements.AsQueryable();

        if (replacementSetId.HasValue)
        {
            replacementQuery = replacementQuery.Where(r => r.CharacterReplacementSetID == replacementSetId.Value); // .AsQueryable();
        }

        var replacementList = await replacementQuery.ToListAsync();

        return replacementList;
    }

[Serializable]
[Table("CharacterReplacementSets", Schema = "SYSTEM")]
public class CharacterReplacementSets
{
    [NavigationPropertyKey]
    [Key]
    public int CharacterReplacementSetID { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public ICollection<CharacterReplacements> CharacterReplacements { get; set; }
    public ICollection<FormatField> FormatFields { get; set; }
    public string CreatedBy { get; set; }
    public DateTime CreatedOn { get; set; }
    public string UpdatedBy { get; set; }
    public DateTime? UpdatedOn { get; set; }
    public string DefaultEncoding { get; set; } // Default character set
    public string DefaultCharacter { get; set; }
    public CharacterReplacementSets()
    {
        CharacterReplacements = new List<CharacterReplacements>();
    }
}

[Serializable]
[Table("CharacterReplacements", Schema = "SYSTEM")]
public class CharacterReplacements
{
    [NavigationPropertyKey]
    [Key]
    public int CharacterReplacementID { get; set; }
    public char OriginalCharacter { get; set; }
    public string ReplacementCharacter { get; set; }
    public string CreatedBy { get; set; }
    public DateTime CreatedOn { get; set; }
    public string UpdatedBy { get; set; }
    public DateTime? UpdatedOn { get; set; }
    [ForeignKey("CharacterReplacementSets")]
    public int CharacterReplacementSetID { get; set; }
}

Ожидаемый результат - Получитьвсе CharacterReplacements, где replaceSetId равен предоставленному replaceSetId.

Фактический результат - Microsoft.Data.SqlClient.SqlException: 'Неверное имя столбца' CharacterReplacementSetsCharacterReplacementSetID '.

Может ли кто-нибудь помочь мне с этим?

1 Ответ

1 голос
/ 11 ноября 2019

Проблема не в конкретном запросе, а в отображении модели.

Во-первых, атрибут ForeignKey здесь

[ForeignKey("CharacterReplacementSets")]
public int CharacterReplacementSetID { get; set; }

не имеет никакого эффекта. При применении к свойству навигации предполагается указание имени свойства FK . И при применении к свойству FK, как здесь, он должен указывать имя навигации свойство . CharacterReplacements не имеет свойства навигации с именем CharacterReplacementSets, поэтому атрибут просто игнорируется. Было бы хорошо, если EF Core генерирует ошибку времени выполнения, чтобы указать на проблему с отображением, но это не так.

Атрибут также был проигнорирован в EF Core 1.x / 2.x. Однако это сработало, потому что имя свойства CharacterReplacementSetID совпадает с именем PK CharacterReplacementSets. Это больше не относится к EF Core 3.0 из-за следующего критического изменения - Соглашение о свойствах внешнего ключа больше не совпадает с именем основного свойства .

Поэтому удалите неверное и вводящее в заблуждение ForeignKey и настройте свойство FK с помощью HasForeignKey fluent API (мой предпочтительный вариант):

modelBuilder.Entity<CharacterReplacementSets>()
    .HasMany(e => e.CharacterReplacements)
    .WithOne()
    .HasForeignKey(e => e.CharacterReplacementSetID);

или с атрибутом ForegnKey для свойства навигации (или свойства обратной навигации, если свойство навигации отсутствует). как здесь):

[ForeignKey("CharacterReplacementSetID")]
public ICollection<CharacterReplacements> CharacterReplacements { get; set; }

Обратите внимание, что у вас может быть похожая проблема с FormatField и другими объектами, использующими аналогичные именованные FK без свойств навигации.

Еще один способ избежать этой проблемы -использовать уникальные имена классов сущностей, такие как CharacterReplacementSet, CharacterReplacement и т. д., поскольку [entity name] + ID по-прежнему соответствует соглашениям EF Core. И вообще, имена в единственном числе лучше / предпочтительнее, даже для удобства чтения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...