EntityFramework Same Table Many to Many Relationship

Ho un tavolo chiamato prodotti che ovviamente contiene prodotti. Tuttavia, ho bisogno di creare prodotti correlati. Quindi quello che ho fatto è creare una tabella di giunzione chiamata product_related che ha due PK. ProductID dalla tabella Prodotti e RelatedID anche dalla tabella Prodotti.

Uso già EF e ho impostato tutto su altri tavoli. Come dovrei aggiungerlo correttamente per creare una relazione con i prodotti in quanto tali: product.Products.Add(product object here) . Ovviamente qui il product rappresenta un object prodotto che ho recuperato dal db usando db.Products.FirstOr...

Come dovrei farlo correttamente? Molti per molti allo stesso tavolo?

Grazie.

Per creare una relazione molti-a-molti con l’ approccio Database-First è necessario configurare uno schema di database che segua determinate regole:

  • Creare una tabella Products con una colonna ProductID come chiave primaria
  • Creare una tabella ProductRelations con una colonna ProductID e una colonna RelatedID e contrassegnare entrambe le colonne come chiave primaria (chiave composita)
  • Non aggiungere altre colonne alla tabella ProductRelations . Le due colonne chiave devono essere le sole colonne della tabella per consentire a EF di riconoscere questa tabella come tabella di collegamento per una relazione molti-a-molti
  • Creare due relazioni di chiavi esterne tra le due tabelle:
    • La prima relazione ha la tabella Products come tabella della chiave primaria con ProductID come chiave primaria e la tabella ProductRelations come tabella della chiave esterna con solo ProductID come chiave esterna
    • La seconda relazione ha anche la tabella Products come tabella della chiave primaria con ProductID come chiave primaria e la tabella ProductRelations come tabella della chiave esterna con solo il RelatedID come chiave esterna
  • Abilita l’ eliminazione a catena per la prima delle due relazioni. (Non è ansible farlo per entrambi. SQL Server non lo consentirà poiché determinerebbe più percorsi di eliminazione sovrapposti).

Se generi un modello di dati di entity framework da quelle due tabelle, ora otterrai solo un’ quadro , ovvero un’ quadro Product (o forse Products se disabiliti la singolarizzazione). La tabella di link ProductRelations non sarà esposta come quadro.

L’ quadro Product avrà due proprietà di navigazione :

 public EntityCollection Products { get { ... } set { ... } } public EntityCollection Products1 { get { ... } set { ... } } 

Queste raccolte di navigazione sono i due endpoint della stessa relazione molti-a-molti. (Se avessi due tavoli diversi che avresti dovuto colbind con una relazione molti-a-molti, ad esempio la tabella A e B , una raccolta di navigazione ( Bs ) sarebbe nell’entity framework A e l’altra ( As ) sarebbe nell’ quadro B poiché la tua relazione è “autoreferenziale”, entrambe le proprietà di navigazione sono nell’entity framework del Product .)

Il significato delle due proprietà sono: I Products sono i prodotti relativi al prodotto dato, I Products1 sono i prodotti che si riferiscono al prodotto dato. Ad esempio: Se la relazione indica che un prodotto ha bisogno di altri prodotti come parti da produrre e si hanno i prodotti “Notebook”, “Processore”, “Chip di silicio”, il “Processore” è costituito da “Silicon chips” (“Silicio”). chip “è un elemento nella raccolta Products dell’ quadro prodotto Processor ) e viene utilizzato da un” Blocco note “(” Notebook “è un elemento della raccolta Products1 dell’ quadro prodotto Processor ). Invece di Products e Products1 i nomi MadeOf e UsedBy sarebbero più appropriati allora.

Puoi tranquillamente eliminare una delle collezioni dal modello generato se sei interessato solo a un lato della relazione. Basta eliminare ad esempio Products1 nella superficie del designer del modello. È anche ansible rinominare le proprietà. La relazione sarà ancora molti a molti.

modificare

Come richiesto in un commento, il modello e la mapping con un approccio Code-First potrebbero essere:

Modello:

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

Mappatura:

 public class MyContext : DbContext { public DbSet Products { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity() .HasMany(p => RelatedProducts) .WithMany() .Map(m => { m.MapLeftKey("ProductID"); m.MapRightKey("RelatedID"); m.ToTable("product_related"); }); } } 

Prendiamo il tuo esempio:

Tabella correlata

  Related_id PK Related_name Date 

Tabella del prodotto

  Product_id PK Related_id FK Product_Name Date 

Come rappresentarlo in EF

Classe di modello correlata denominata come RelatedModel

  [Key] public int Related_id { get; set; } public string Related_name {get;set} public Datetime Date{get;set;} 

Classe del modello di prodotto denominata 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; } 

In questo modo possiamo creare relazioni tra due tabelle

Ora, nel caso di molte o molte relazioni vorrei fare un altro esempio qui

Supponiamo che abbia un modello Class 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; } } 

Qui CourseID e StudentId sono le due chiavi straniere

Ora ho un altro corso di class.cs in cui creeremo relazione molti a molti.

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

Spero che questo ti possa aiutare !!!