Подтвердить что ты не робот

EntityFramework - одна и та же таблица Многие для многих отношений

У меня есть таблица под названием Продукты, которая, очевидно, содержит продукты. Однако мне нужно создать похожие продукты. Так что я сделал, это создать таблицу соединений, называемую product_related, которая имеет два PK. ProductID from Products и RelatedID также из таблицы Products.

Я уже использую EF и настроил все на других таблицах. Как я должен добавить это правильно, чтобы создать отношения с продуктами как таковыми: product.Products.Add(product object here). Конечно, здесь product представляет объект продукта, который я извлек из db с помощью db.Products.FirstOr....

Как я должен делать это правильно? Многим для многих в одну и ту же таблицу?

Спасибо.

4b9b3361

Ответ 1

Чтобы создать отношение "многие ко многим" с базовым подходом, вам необходимо настроить схему базы данных, которая следует определенным правилам:

  • Создайте таблицу Products со столбцом ProductID в качестве первичного ключа
  • Создайте таблицу ProductRelations со столбцом ProductID и столбцом RelatedID и пометьте оба столбца как первичный ключ (составной ключ)
  • Не добавляйте другой столбец в таблицу ProductRelations. Два ключевых столбца должны быть единственными столбцами в таблице, чтобы позволить EF распознавать эту таблицу как таблицу ссылок для отношения "многие-ко-многим".
  • Создайте две отношения внешнего ключа между двумя таблицами:
    • Первое отношение имеет таблицу Products как таблицу первичного ключа с ProductID как первичный ключ, а таблицу ProductRelations - как таблицу внешнего ключа с только ProductID как внешний ключ
    • Второе соотношение также имеет таблицу Products в качестве первичной таблицы ключей с ProductID в качестве первичного ключа, а таблицу ProductRelations - как таблицу внешнего ключа с только RelatedID как иностранную ключ
  • Включить каскадное удаление для первого из двух отношений. (Вы не можете сделать это для обоих. SQL Server не позволит этого, потому что это приведет к нескольким каскадным путям удаления.)

Если вы создадите модель данных сущности из этих двух таблиц, теперь вы получите только один объект, а именно объект Product (или, возможно, Products, если вы отключите сингулярность). Таблица ссылок ProductRelations не будет отображаться как объект.

Объект Product будет иметь два свойства навигации:

public EntityCollection<Product> Products { get { ... } set { ... } }
public EntityCollection<Product> Products1 { get { ... } set { ... } }

Эти навигационные коллекции являются двумя конечными точками одного и того же отношения "многие ко многим" . (Если у вас было две разные таблицы, которые вы хотели связать по принципу "многие ко многим" , скажем, таблица A и B, одна коллекция навигации (Bs) будет находиться в сущности A, а другая (As) будет в объекте B. Но поскольку ваши отношения являются "саморегуляционными", оба свойства навигации находятся в объекте Product.)

Смысл двух свойств: Products являются продуктами, связанными с данным продуктом, Products1 являются продуктами, которые относятся к данному произведению. Например: Если это означает, что продукт нуждается в других продуктах в качестве деталей, которые должны быть изготовлены, и у вас есть продукты "Ноутбук", "Процессор", "Кремниевые чипы", тогда "Процессор" выполнен из "Silicon chips" ( "Silicon chips" - это элемент в коллекции Products продукта продукта Processor) и используется a "Блокнот" ( "Блокнот" - это элемент в Products1 совокупность объекта продукта Processor). Вместо Products и Products1 имена MadeOf и UsedBy были бы более подходящими.

Вы можете безопасно удалить одну из коллекций из сгенерированной модели, если вас интересует только одна сторона отношения. Просто удалите, например, Products1 на поверхности модели дизайнера. Вы также можете переименовать свойства. Связь будет по-прежнему много-ко-многим.

Edit

Как указано в комментарии, модель и сопоставление с использованием Code-First:

Модель:

public class Product
{
    public int ProductID { get; set; }

    public ICollection<Product> RelatedProducts { get; set; }
}

Mapping:

public class MyContext : DbContext
{
    public DbSet<Product> Products { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Product>()
            .HasMany(p => RelatedProducts)
            .WithMany()
            .Map(m =>
            {
                m.MapLeftKey("ProductID");
                m.MapRightKey("RelatedID");
                m.ToTable("product_related");
            });
    }
}

Ответ 2

Давайте возьмем ваш пример:

Связанная таблица -

  Related_id      PK
  Related_name
  Date

Продукт Таблица <

  Product_id      PK
  Related_id      FK
  Product_Name
  Date

Как представлять его в EF

Класс связанной модели, названный как RelatedModel

  [Key]
  public int Related_id { get; set; }

  public string Related_name {get;set}

  public Datetime Date{get;set;}

Класс модели продукта, названный как ProductModel

   [Key]
  public int Product_id { get; set; }

  public string Product_name {get;set}

  public string Related_id {get;set}

  public Datetime Date{get;set;}

  [ForeignKey("Related_id ")]      //We  can also specify here Foreign key
  public virtual RelatedModel Related { get; set; } 

Таким образом, мы можем создать отношения между двумя таблицами

Теперь в случае отношения "многие ко многим" Я хотел бы взять здесь еще один пример

Предположим, что у меня есть класс Model Enrollment.cs

public class Enrollment
{
    public int EnrollmentID { get; set; }
    public int CourseID { get; set; }
    public int StudentID { get; set; }
    public decimal? Grade { get; set; }
    public virtual Course Course { get; set; }
    public virtual Student Student { get; set; }
}

Здесь CourseID и StudentId - это два внешних ключа

Теперь у меня есть еще один класс Course.cs, где мы создадим отношение "многие-многие".

public class Course
{
    public int CourseID { get; set; }
    public string Title { get; set; }
    public int Credits { get; set; }
    public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Надеюсь, это поможет!!!