简体   繁体   English

EntityFramework同桌多对多关系

[英]EntityFramework Same Table Many to Many Relationship

I have a table called Products which obviously contains products. 我有一个名为Products的表,显然包含产品。 However, I need to create related products. 但是,我需要创建相关产品。 So what I've done is create a junction table called product_related which has two PKs. 所以我所做的就是创建一个名为product_related的联结表,它有两个PK。 ProductID from Products table and RelatedID also from Products table. Products表中的ProductID和Products表中的RelatedID。

I already use EF and have set up everything on other tables. 我已经使用EF并在其他表上设置了所有内容。 How should I add this properly in order to create a relationship with products as such: product.Products.Add(product object here) . 我应该如何正确添加它以便与产品建立关系: product.Products.Add(product object here)product.Products.Add(product object here) Of course here product represent a product object that I've fetched from the db using db.Products.FirstOr... . 当然,这里的product代表了我使用db.Products.FirstOr...从db中获取的产品对象db.Products.FirstOr...

How should I do this properly ? 我该怎么做呢? A many to many to the same table? 同桌的多对多?

Thanks. 谢谢。

In order to create a many-to-many relationship with Database-First approach you need to setup a database schema that follows certain rules: 为了使用Database-First方法创建多对多关系,您需要设置遵循某些规则的数据库模式:

  • Create a Products table with a column ProductID as primary key 使用ProductID列作为主键创建Products
  • Create a ProductRelations table with a column ProductID and a column RelatedID and mark both columns as primary key (composite key) 使用列ProductID和列RelatedID创建ProductRelations表,并将这两列标记为主键 (组合键)
  • Don't add any other column to the ProductRelations table . 不要将任何其他列添加到ProductRelations The two key columns must be the only columns in the table to let EF recognize this table as a link table for a many-to-many relationship 两个键列必须是表中唯一的列,以便EF将此表识别为多对多关系的链接表
  • Create two foreign key relationships between the two tables: 在两个表之间创建两个外键关系
    • The first relationship has the Products table as primary-key-table with the ProductID as primary key and the ProductRelations table as foreign-key-table with only the ProductID as foreign key 第一个关系将Products表作为primary-key-table, ProductID作为主键, ProductRelations表作为foreign-key-table, 只有ProductID作为外键
    • The second relationship also has the Products table as primary-key-table with the ProductID as primary key and the ProductRelations table as foreign-key-table with only the RelatedID as foreign key 第二个关系也将Products表作为primary-key-table, ProductID作为主键, ProductRelations表作为foreign-key-table, 只有RelatedID作为外键
  • Enable cascading delete for the first of the two relationships. 为两个关系中的第一个启用级联删除 (You can't do it for both. SQL Server won't allow this because it would result in multiple cascading delete paths.) (你不能两者都做.SQL Server不允许这样做,因为它会导致多个级联删除路径。)

If you generate an entity data model from those two tables now you will get only one entity , namely a Product entity (or maybe Products if you disable singularization). 如果从这两个表生成实体数据模型,现在只能获得一个实体 ,即Product实体(如果禁用单一化,则可能是Products )。 The link table ProductRelations won't be exposed as an entity. 链接表ProductRelations不会作为实体公开。

The Product entity will have two navigation properties : Product实体将具有两个导航属性

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

These navigation collections are the two endpoints of the same many-to-many relationship. 这些导航集合是相同多对多关系的两个端点。 (If you had two different tables you wanted to link by a many-to-many relationship, say table A and B , one navigation collection ( Bs ) would be in entity A and the other ( As ) would be in entity B . But because your relationship is "self-referencing" both navigation properties are in entity Product .) (如果你有两个不同的表,你想通过多对多关系链接,比如表AB ,一个导航集合( Bs )将在实体A ,另一个( As )将在实体B 。但是因为您的关系是“自引用”,两个导航属性都在实体Product 。)

The meaning of the two properties are: Products are the products related to the given product, Products1 are the products that refer to the given product. 这两个属性的含义是: Products是与给定产品相关的产品, Products1是指给定产品的产品。 For example: If the relationship means that a product needs other products as parts to be manufactured and you have the products "Notebook", "Processor", "Silicon chips" then the "Processor" is made of "Silicon chips" ("Silicon chips" is an element in the Products collection of the Processor product entity) and is used by a "Notebook" ("Notebook" is an element in the Products1 collection of the Processor product entity). 例如:如果关系意味着产品需要其他产品作为制造零件,并且您拥有产品“笔记本”,“处理器”,“硅芯片”,那么“处理器” “硅芯片” 制成( “硅芯片” chips“是Processor产品实体的Products集合中的元素”, “Notebook”使用(“Notebook”是Processor产品实体的Products1集合中的元素)。 Instead of Products and Products1 the names MadeOf and UsedBy would be more appropriate then. 而不是ProductsProducts1 ,名称MadeOfUsedBy将更合适。

You can safely delete one of the collections from the generated model if you are only interested in one side of the relationship. 如果您只对关系的一方感兴趣,则可以安全地从生成的模型中删除其中一个集合。 Just delete for example Products1 in the model designer surface. 只需删除模型设计器表面中的Products1 You can also rename the properties. 您还可以重命名属性。 The relationship will still be many-to-many. 这种关系仍然是多对多的。

Edit 编辑

As asked in a comment the model and mapping with a Code-First approach would be: 正如评论中所述,使用Code-First方法的模型和映射将是:

Model: 模型:

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

Lets take your Example: 让我们举例:

Related table 相关表格

  Related_id      PK
  Related_name
  Date

Product Table 产品

  Product_id      PK
  Related_id      FK
  Product_Name
  Date

How to Represent it in EF 如何在EF中表示它

Related Model Class named as RelatedModel 相关模型类,名为RelatedModel

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

  public string Related_name {get;set}

  public Datetime Date{get;set;}

Product Model Class named as ProductModel 名为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 this way we can Create Relations between Two table 通过这种方式我们可以创建两个表之间的关系

Now In Case of Many to Many Relation I would like to take another Example here 现在在多对多关系的情况下我想在这里采取另一个例子

Suppose I have a Model Class Enrollment.cs 假设我有一个Model 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; }
}

Here CourseID and StudentId are the two foreign Keys 这里CourseID和StudentId是两个外键

Now I Have another Class Course.cs where we will create Many to Many Relation. 现在我有另一个类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; }
}

Hope This will help!!! 希望这会有所帮助!!!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM