EF Code First具有多对多的自引用关系

时间:2011-03-11 13:36:29

标签: entity-framework-4 many-to-many entity-framework-ctp5 self-reference

我开始使用EF Code First和MVC,我有点难过。我有以下数据库结构(很抱歉,我不允许发布图片):

表 - 产品
表 - RelatedProducts

在Products.ProductID上的1-多个 - > RelatedProducts.ProductID
Products.ProductID上的1-多个 - > RelatedProducts.RelatedProductID

基本上我的产品可以有一系列与之相关的产品。它们保存在RelatedProducts表中,其中包含ProductID和相关产品的ProductID定义的关系,我将其命名为RelatedProductID。在我的代码中,我创建了以下类:

public class MyDBEntities : DbContext
{
    public DbSet<Product> Products { get; set; }
    public DbSet<RelatedProduct> RelatedProducts { get; set; }
}

public class Product
{
    public Guid ProductID { get; set; }
    public string Name { get; set; }
    public string Heading { get; set; }
    public string Description { get; set; }
    public decimal Price { get; set; }
    public Guid CategoryID { get; set; }
    public string ImageURL { get; set; }
    public string LargeImageURL { get; set; }
    public string Serves { get; set; }
    public virtual List<RelatedProduct> RelatedProducts { get; set; }
}
public class RelatedProduct
{
    public Guid ProductID { get; set; }
    public Guid RelatedProductID { get; set; }
    public virtual Product Product { get; set; }
    public virtual Product SimilarProduct { get; set; }
}

然后我尝试使用以下代码访问这些:

myDB.Products.Include("RelatedProducts").Where(x => x.ProductID == productID).FirstOrDefault();

但我一直收到以下错误:

{"Invalid column name 'ProductProductID2'.\r\nInvalid column name 'ProductProductID2'.\r\nInvalid column name 'ProductProductID'.\r\nInvalid column name 'ProductProductID1'.\r\nInvalid column name 'ProductProductID2'."}

我做错了什么?我基本上想要获得一个产品,然后遍历Rel​​atedProducts并显示该产品信息。

1 个答案:

答案 0 :(得分:10)

答案的第一部分是EF4 CTP5没有正确地将您的POCO映射到数据库,因为它不够智能。如果你签出数据库,你会得到:

    CREATE TABLE RelatedProducts(
        RelatedProductID uniqueidentifier NOT NULL,
        ProductID uniqueidentifier NOT NULL,
        ProductProductID uniqueidentifier NULL,
        ProductProductID1 uniqueidentifier NULL,
        ProductProductID2 uniqueidentifier NULL,
        PRIMARY KEY CLUSTERED 
        (
            RelatedProductID ASC
        )
    ) ON [PRIMARY]  

呸!这需要通过一些手动工作来解决。在DbContext中,添加如下规则:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Product>()
            .Property(p => p.ProductID)
            .HasDatabaseGenerationOption(DatabaseGenerationOption.Identity);

        modelBuilder.Entity<RelatedProduct>()
            .HasKey(rp => new { rp.ProductID, rp.RelatedProductID });

        modelBuilder.Entity<Product>()
            .HasMany(p => p.RelatedProducts)
            .WithRequired(rp => rp.Product)
            .HasForeignKey(rp => rp.ProductID)
            .WillCascadeOnDelete();

        modelBuilder.Entity<RelatedProduct>()
            .HasRequired(rp => rp.SimilarProduct)
            .WithMany()
            .HasForeignKey(rp=> rp.RelatedProductID)
            .WillCascadeOnDelete(false);

        base.OnModelCreating(modelBuilder);
    }