Отношение ядра EF в неправильном направлении

#.net #entity-framework-core #one-to-many

#.net #сущность-фреймворк-ядро #один ко многим

Вопрос:

У меня есть продукты с аллергией. Однако, когда я пытаюсь смоделировать это в EF core, я не могу заставить работать отношение «один ко многим». EF создает новое поле ProductID в Allergies, и поэтому только у 1 продукта может быть 1 аллергия.

Это мой код:

    public class Product
    {
        [Key]
        public int ProductId { get; set; }
        public string Name{ get; set; }
        public byte[] ImageData { get; set; }
        public virtual ICollection<Allergie> Allergies { get; set; }
    }

  public class Allergy
    {
        [Key]
        public int AllergyId { get; set;  }
        public string Name{ get; set; }
    }
  

Похоже, это приводит к взаимно однозначному отношению (при этом аллергия в конечном итоге также имеет ProductID). Как я могу это исправить?

Спасибо!

Ответ №1:

Похоже, это приводит к взаимно однозначному отношению (при этом аллергия в конечном итоге также имеет ProductID). Как я могу это исправить?

Исправлять нечего, потому что это правильная реализация отношения «один ко многим» для реляционной базы данных.

Отношения всегда имеют две стороны, а кратность {from}- {to} зависит от того, с какой стороны отношения вы смотрите. Таким образом, с Product одной стороны, это один ко многим, а со Allergy стороны — много к одному. т. Е. У каждого Allergy есть ровно один Product , который в базе данных представлен с помощью столбца FK при Allergy ссылке на PK Product .

Помните, что таблицы базы данных являются плоскими, поэтому свойство навигации по коллекции Product.Allergies для данного product запроса представляет такой

 db.Allergies.Where(allergy => allergy.ProductId == product.Id)
  

Это дает вам много аллергий на продукт, поскольку таблица ProductId in Allergy не уникальна. Однако столбец Id , на Product который ссылается таблица, уникален, поэтому свойство обратной навигации по ссылкам Allergy.Product будет представлять для данного allergy запроса примерно так

 db.Products.Single(product => product.Id == allergy.ProductId)
  

Ссылка: Отношения в документации ядра EF.


С учетом сказанного, не желая FK в Allergy вас, вероятно, ищут отношения «многие ко многим«. Для этого типа отношений требуется дополнительная таблица «link» («join»), а в текущей версии ядра EF (3.1) требуется явный класс сущности, как описано в документации ссылка:

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

Предстоящее EF Core 5.0 добавит поддержку отношений «многие ко многим» без явного отображения таблицы соединений, что упростит создание таких отношений, но до тех пор вам придется использовать вышеупомянутый подход.