Entity Framework Code First Self Referencing Parent Child with Payload

故事扮演 提交于 2019-12-18 08:29:44

问题


I'm attempting to set this up using code first in entity framework and am running into difficulty. To describe what i'm trying to accomplish:

Have an entity of Product. This product optionally may have one or more related "child" products. A product can be the child to one or more parent products.

when I go to generate a controller tied to the model class "Product", i'm getting an error: (updated, more specific, matches code below)

 There was an error running the selected code generator:
'Unable to retrieve metadata for 'ProductCatalog.Models.Product'.
 Multiple object sets per type are not supported. The object sets 
'Product' and 'Products' can both contain instances of type
'ProductCatalog.Models.Product'.

here's the not working model class:

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;

namespace ProductCatalog.Models
{
    // Product
    public class Product
    {
        [Key]
        public int ProductId { get; set; } // ProductID (Primary key)
        public string ProductName { get; set; } // ProductName
        public string ProductSku { get; set; } // ProductSKU
        public int BaseQuantity { get; set; } // BaseQuantity
        public decimal BaseCost { get; set; } // BaseCost

        // Reverse navigation
        public virtual ICollection<RelatedProduct> ParentProducts { get; set; } // RelatedProduct.FK_RelatedProductChildID
        public virtual ICollection<RelatedProduct> ChildProducts { get; set; } // RelatedProduct.FK_RelatedProductParentID

        public virtual ICollection<RelatedProduct> RelatedProducts { get; set; }
    }


    // RelatedProduct
    public class RelatedProduct
    {
        [Key, Column(Order = 0)]
        public int ParentId { get; set; } // ParentID
        [Key, Column(Order = 1)]
        public int ChildId { get; set; } // ChildID
        public int Quantity { get; set; } // Quantity
        public bool Required { get; set; } // Required
        public bool Locked { get; set; } // Locked

        // Foreign keys
        public virtual Product ParentProduct { get; set; } //  FK_RelatedProductParentID
        public virtual Product ChildProduct { get; set; } //  FK_RelatedProductChildID
    }

    public class ProductDBContext : DbContext
    {
        public IDbSet<Product> Product { get; set; } // Product
        public IDbSet<RelatedProduct> RelatedProduct { get; set; } // RelatedProduct

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<RelatedProduct>()
                .HasRequired(a => a.ParentProduct)
                .WithMany(b => b.ChildProducts)
                .HasForeignKey(c => c.ParentId) // FK_RelatedProductParentID
                .WillCascadeOnDelete(false);

            modelBuilder.Entity<RelatedProduct>()
                .HasRequired(a => a.ChildProduct)
                .WithMany(b => b.ParentProducts)
                .HasForeignKey(c => c.ChildId); // FK_RelatedProductChildID

        }
    }
}

回答1:


fixed by pluralizing the DbSets

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;

namespace ProductCatalog.Models
{
    // Product
    public class Product
    {
        [Key]
        public int ProductId { get; set; } // ProductID (Primary key)
        public string ProductName { get; set; } // ProductName
        public string ProductSku { get; set; } // ProductSKU
        public int BaseQuantity { get; set; } // BaseQuantity
        public decimal BaseCost { get; set; } // BaseCost

        // Reverse navigation
        public virtual ICollection<RelatedProduct> ParentProducts { get; set; } // RelatedProduct.FK_RelatedProductChildID
        public virtual ICollection<RelatedProduct> ChildProducts { get; set; } // RelatedProduct.FK_RelatedProductParentID

        public virtual ICollection<RelatedProduct> RelatedProducts { get; set; }
    }


    // RelatedProduct
    public class RelatedProduct
    {
        [Key, Column(Order = 0)]
        public int ParentId { get; set; } // ParentID
        [Key, Column(Order = 1)]
        public int ChildId { get; set; } // ChildID
        public int Quantity { get; set; } // Quantity
        public bool Required { get; set; } // Required
        public bool Locked { get; set; } // Locked

        // Foreign keys
        public virtual Product ParentProduct { get; set; } //  FK_RelatedProductParentID
        public virtual Product ChildProduct { get; set; } //  FK_RelatedProductChildID
    }

    public class ProductDBContext : DbContext
    {
        public IDbSet<Product> Products { get; set; } // Product
        public IDbSet<RelatedProduct> RelatedProducts { get; set; } // RelatedProduct

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<RelatedProduct>()
                .HasRequired(a => a.ParentProduct)
                .WithMany(b => b.ChildProducts)
                .HasForeignKey(c => c.ParentId) // FK_RelatedProductParentID
                .WillCascadeOnDelete(false);

            modelBuilder.Entity<RelatedProduct>()
                .HasRequired(a => a.ChildProduct)
                .WithMany(b => b.ParentProducts)
                .HasForeignKey(c => c.ChildId); // FK_RelatedProductChildID

        }
    }
}


来源:https://stackoverflow.com/questions/20916873/entity-framework-code-first-self-referencing-parent-child-with-payload

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!