简体   繁体   中英

EF with many to many relation on the same table with another attributes

I could' t do a many to many relationship on the same table with ef code first. Is there anyone can help me? I have a Category class and a CategoryRelation class too. Categoy class has many Parent Categories and many Child Categories. But i have a extra prop as DisplayId in CategoryRelation. My classes are like following

Category:

 public class Category : Base
{
    #region Top Menu
    public int DisplayOrder { get; set; }
    public bool ShowOnTopMenu { get; set; }
    #endregion

    public bool ShowOnTopSelling { get; set; }
    [MaxLength(100)]
    public string Name { get; set; }

    #region Types
    public bool IsPieceType { get; set; }
    public bool IsGildingType { get; set; }
    public bool IsPaperType { get; set; }
    public bool IsSizeType { get; set; }
    public bool IsWeightType { get; set; }
    public bool IsCellophaneType { get; set; }
    public bool IsCuttingType { get; set; }
    public bool IsPrintingType { get; set; }
    #endregion

    public virtual ICollection<CategoryRelation> ChildCategoryList { get; set; }    
    public virtual ICollection<CategoryRelation> ParentCategoryList { get; set; }
    public virtual ICollection<Product> ProductList { get; set; }
    public virtual ICollection<WishList> WishList { get; set; }
    public virtual ICollection<Description> DescriptionList { get; set; }
    public virtual ICollection<Comment> CommentList { get; set; }
    public virtual ICollection<Image> ImageList { get; set; }
    public virtual ICollection<Template> TemplateList { get; set; }
    public virtual ICollection<PromotionCode> PromotionCodeList { get; set; }
}

CategoryRelation;

public class CategoryReletion : Base
    {
        #region Parent Category
        [ForeignKey("ParentCategory")]
        public int ParentId { get; set; }
        public Category ParentCategory { get; set; }
        #endregion

        #region Child Category
        [ForeignKey("ChildCategory")]
        public int ChildId { get; set; }
        public Category ChildCategory { get; set; }
        #endregion
        public int DisplayOrder { get; set; }
    }

Finally i'm getting this error;

Introducing FOREIGN KEY constraint 'FK_dbo.CategoryReletion_dbo.Category_ParentId' on table 'CategoryReletion' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. Could not create constraint or index. See previous errors.*

It worked with these codes;

       modelBuilder.Entity<CategoryRelation>()
              .HasKey(c => new { c.ParentId, c.ChildId });

        modelBuilder.Entity<CategoryRelation>()
              .HasRequired(c => c.ParentCategory)
              .WithMany(c => c.ChildCategoryList)
              .HasForeignKey(c => c.ParentId)
              .WillCascadeOnDelete(false);

        modelBuilder.Entity<CategoryRelation>()
            .HasRequired(c => c.ChildCategory)
            .WithMany(c => c.ParentCategoryList)
            .HasForeignKey(c => c.ChildId)
            .WillCascadeOnDelete(false);

You can do exactly as you are told (I assume that your context is name MyContext )

public class MyContext: DbContext
{
    public DbSet<Category> Categories { get; set; }
    public DbSet<CategoryReletion> CategoryReletions { get; set; }

      protected override void OnModelCreating( DbModelBuilder modelBuilder )
      {
         modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
         modelBuilder.Entity<CategoryReletion>()
            .HasRequired( c => c.ParentId)
            .WithRequiredDependent()
            .WillCascadeOnDelete(false);

         modelBuilder.Entity<CategoryReletion>()
            .HasRequired( c => c.ChildId)
            .WithRequiredDependent()
            .WillCascadeOnDelete(false);
      }

}

This happens because of the multiple many to many relationships.

and you have cascadeDelete On which means if you delete a row all the related rows will be deleted imagine how this works on multiple relationships, you may end with a delete order for a deleted row.

So to solve this you need to use FluentApi to turn CascadeDelete off

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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