Seda Özdemir
Seda Özdemir

Reputation: 43

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.*

Upvotes: 1

Views: 105

Answers (3)

Seda &#214;zdemir
Seda &#214;zdemir

Reputation: 43

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

Upvotes: 1

Ahmed Salim
Ahmed Salim

Reputation: 71

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

Upvotes: 0

Athanasios Kataras
Athanasios Kataras

Reputation: 26372

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

}

Upvotes: 0

Related Questions