首先在实体框架代码中与中间对象进行多对多映射

Posted

技术标签:

【中文标题】首先在实体框架代码中与中间对象进行多对多映射【英文标题】:many to many mapping with intermediate object in entity framework code first 【发布时间】:2012-09-07 13:40:49 【问题描述】:

我有一个多对多关系,我想添加一个中间类,这将使我能够使用存储库模式添加多对多关系。

我想不通的是映射。

这是结构

public class Product

    public Product()
    
        Categories = new HashSet<Category>();
    

    public int  Id  get; set; 
    public string Name  get; set; 

    public ICollection<Category> Categories  get; set; 


public class Category

    public int Id  get; set; 
    public String Name  get; set; 

    public ICollection<Product> Products  get; set; 



public class PCMap

    public int product_id  get; set; 
    public int category_id  get; set; 

    public Product Product  get; set; 
    public Category Category  get; set; 

还有映射

modelBuilder.Entity<Product>()
    .HasEntitySetName("PCMap")
    .HasMany(p=>p.Categories)
    .WithMany(p=>p.Products)
    .Map(m=>
        
            m.MapLeftKey("product_id");
            m.MapRightKey("category_id");
            m.ToTable("PCMap");
        );

modelBuilder.Entity<PCMap>()
    .ToTable("PCMap");

modelBuilder.Entity<PCMap>().HasKey(k => new
    
        k.category_id,
        k.product_id
    );

modelBuilder.Entity<PCMap>()
    .HasRequired(p=>p.Product)
    .WithMany()
    .HasForeignKey(p => p.product_id);

modelBuilder.Entity<PCMap>()
    .HasRequired(p => p.Category)
    .WithMany()
    .HasForeignKey(p => p.category_id);

这是我得到的错误.. 我该如何解决 ?

【问题讨论】:

【参考方案1】:

您的设置方式。 PCMap 是一个非实体,仅用于促进幕后的 M:N 连接。

Product p = new Product();
p.Categories ...

Category c = new Category();
c.Products ...

因为您已经在这里将 PC 定义为产品实体定义的一部分。

.Map(m=>
        
            m.MapLeftKey("product_id");
            m.MapRightKey("category_id");
            m.ToTable("PCMap");
        );

我认为您不需要(或者可以)再次定义它,下面分别进行定义。尝试删除所有这些代码。

modelBuilder.Entity<PCMap>()
    .ToTable("PCMap");
modelBuilder.Entity<PCMap>().HasKey(k => new
    
        k.category_id,
        k.product_id
    );

modelBuilder.Entity<PCMap>()
    .HasRequired(p=>p.Product)
    .WithMany()
    .HasForeignKey(p => p.product_id);

modelBuilder.Entity<PCMap>()
    .HasRequired(p => p.Category)
    .WithMany()
    .HasForeignKey(p => p.category_id);

【讨论】:

是的,删除此代码可消除错误。我的问题是 - 我需要访问该表(PCMap)。我想要的是能够直接实例化 PCMap 实例并将其保存到数据库中 啊。那么您不想按照您所做的方式创建映射。相反,您希望拥有像 Product.PCMaps.CategoriesCategory.PCMaps.Products 这样的关系。我不认为你可以同时拥有它。 您不能将实体作为联结点,并保持直接导航属性。见this post

以上是关于首先在实体框架代码中与中间对象进行多对多映射的主要内容,如果未能解决你的问题,请参考以下文章

(转)Hibernate框架基础——多对多关联关系映射

实体框架多对多异常与继承

如何在实体框架中创建多对多映射?

Hibernate多表关系配置——多对多对关系映射

实体框架数据库首先生成多对多中间表,其中没有额外的列

Hibernate多对多关系映射(建表)