web-dev-qa-db-fra.com

EntityFramework même table plusieurs à plusieurs relation

J'ai un tableau appelé Produits qui contient évidemment des produits. Cependant, je dois créer des produits associés. Donc, ce que j'ai fait, c'est créer une table de jonction appelée product_related qui a deux PK. ProductID de la table Products et RelatedID également de la table Products.

J'utilise déjà EF et j'ai tout configuré sur d'autres tables. Comment dois-je l'ajouter correctement afin de créer une relation avec les produits en tant que tels: product.Products.Add(product object here). Bien sûr, ici product représente un objet produit que j'ai récupéré à partir de la base de données en utilisant db.Products.FirstOr....

Comment dois-je procéder correctement? Plusieurs à plusieurs à la même table?

Merci.

47
user1027620

Afin de créer une relation plusieurs-à-plusieurs avec l'approche Database-First , vous devez configurer un schéma de base de données qui suit certaines règles:

  • Créer une table Products avec une colonne ProductID comme clé primaire
  • Créez une table ProductRelations avec une colonne ProductID et une colonne RelatedID et marquez les deux colonnes comme clé primaire (clé composite)
  • N'ajoutez aucune autre colonne à la table ProductRelations. Les deux colonnes clés doivent être les seules colonnes du tableau pour permettre à EF de reconnaître ce tableau comme une table de liens pour une relation plusieurs-à-plusieurs
  • Créez deux relations de clé étrangère entre les deux tables:
    • La première relation a la table Products comme table de clé primaire avec la ProductID comme clé primaire et la table ProductRelations comme table de clé étrangère avec uniquement le ProductID comme clé étrangère
    • La deuxième relation a également la table Products comme table de clé primaire avec la ProductID comme clé primaire et la table ProductRelations comme table de clé étrangère avec uniquement le RelatedID comme clé étrangère
  • Activez la suppression en cascade pour la première des deux relations. (Vous ne pouvez pas le faire pour les deux. SQL Server ne permet pas cela car cela entraînerait plusieurs chemins de suppression en cascade.)

Si vous générez un modèle de données d'entité à partir de ces deux tables, vous obtiendrez une seule entité , à savoir une entité Product (ou peut-être Products si vous désactivez la singularisation). La table de liens ProductRelations ne sera pas exposée en tant qu'entité.

L'entité Product aura deux propriétés de navigation :

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

Ces collections de navigation sont les deux points de terminaison de la même relation plusieurs-à-plusieurs. (Si vous vouliez lier deux tables différentes par une relation plusieurs-à-plusieurs, par exemple la table A et B, une collection de navigation (Bs) serait dans l'entité A et l'autre (As) seraient dans l'entité B. Mais parce que votre relation est "auto-référencée", les deux propriétés de navigation sont dans l'entité Product.)

La signification des deux propriétés est: Products sont les produits liés au produit donné, Products1 sont les produits qui se réfèrent au produit donné. Par exemple: si la relation signifie qu'un produit a besoin d'autres produits en tant que pièces à fabriquer et que vous avez les produits "Notebook", "Processor", "Silicon chips" alors le "Processor" est fait de "puces de silicium" ("puces de silicium" est un élément de la collection Products de l'entité de produit Processor) et est utilisé par un "Notebook" ("Notebook" est un élément du Products1 collection de l'entité de produit Processor). Au lieu de Products et Products1 les noms MadeOf et UsedBy seraient alors plus appropriés.

Vous pouvez supprimer en toute sécurité l'une des collections du modèle généré si vous n'êtes intéressé que par un côté de la relation. Supprimez simplement par exemple Products1 dans la surface du concepteur de modèle. Vous pouvez également renommer les propriétés. La relation sera toujours de plusieurs à plusieurs.

Modifier

Comme demandé dans un commentaire, le modèle et le mappage avec une approche Code-First seraient:

Modèle:

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

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

Cartographie:

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");
            });
    }
}
82
Slauma

Prenons votre exemple:

Associé table

  Related_id      PK
  Related_name
  Date

Produit Table

  Product_id      PK
  Related_id      FK
  Product_Name
  Date

Comment le représenter dans EF

classe de modèle associée nommée RelatedModel

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

  public string Related_name {get;set}

  public Datetime Date{get;set;}

Product Model Class nommé 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; } 

De cette façon, nous pouvons créer des relations entre deux tables

Maintenant, en cas de relation plusieurs à plusieurs, je voudrais prendre un autre exemple ici

Supposons que j'ai une classe modèle 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; }
}

Ici CourseID et StudentId sont les deux clés étrangères

Maintenant, j'ai une autre classe Course.cs où nous allons créer une relation plusieurs à plusieurs.

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; }
}

J'espère que cela vous aidera !!!

0
RL89