關於EF中出現FOREIGNKEY約束可能會導致循環或多重級聯路徑的問題


ef中,我們創建外鍵的時候需要注意,否則會出現標題所示問題。

例:有項目表,項目收藏表,用戶表

項目表有如下字段:ProjectId,InputPersonId等

項目收藏表有如下字段:ProjectId,UseId等

用戶表有如下字段:用戶id等

項目表:

 public partial class ProjectInfoMap : EntityTypeConfiguration<ProjectInfo>
    {
        public ProjectInfoMap()
        { 
            this.ToTable("ProjectInfo");
            this.HasKey(pr => pr.Id);
            this.Property(pr => pr.Id).HasColumnName("ProjectId");
            this.HasRequired(pr => pr.InputPerson)
             .WithMany()
             .HasForeignKey(pr => pr.InputPersonId);

        }
    }

項目收藏表:

 public partial class ProjectCollectMap : EntityTypeConfiguration<ProjectCollect>
    {
        public ProjectCollectMap()
        {
            this.ToTable("ProjectCollect");
            this.HasKey(pc => pc.Id);

            this.HasRequired(pc => pc.ProjectInfo)
                .WithMany(p => p.ProjectCollects)
                .HasForeignKey(pc => pc.ProjectId);

            this.HasRequired(pc => pc.User)
                .WithMany(u=>u.ProjectCollects)
                .HasForeignKey(pc => pc.UserId);
        }
    }

用戶表:

public partial class UserMap: EntityTypeConfiguration<User>
    {
        public SISTUserMap()
        {
            this.ToTable("User");
            this.HasKey(u => u.Id);
            this.Property(u => u.Id).HasColumnName("UserId");
        }
    
    }

分析一下,假如刪除用戶表的某個用戶數據,

則有如下級聯刪除,即刪除用戶的時候有多個路徑可以級聯刪除項目收藏表,則會出現標題所示錯誤

刪除用戶 -> 刪除項目 -> 刪除項目收藏表(這里刪除項目的同時會刪除項目收藏表)

刪除用戶 -> 刪除項目收藏表

 

解決方法如下:

1.刪除其中一個級聯刪除,代碼如下所示,不建議這樣做,因為這樣的映射原本就不太恰當。

 public partial class ProjectInfoMap : EntityTypeConfiguration<ProjectInfo>
    {
        public ProjectInfoMap()
        { 
            this.ToTable("ProjectInfo");
            this.HasKey(pr => pr.Id);
            this.Property(pr => pr.Id).HasColumnName("ProjectId");
            this.HasRequired(pr => pr.InputPerson)
             .WithMany()
             .HasForeignKey(pr => pr.InputPersonId)
             .WillCascadeOnDelete(false);

        }
    }

 

2.將InputPerson映射為輸入用戶-項目表,即用另外一張表關聯輸入用戶和項目id。同時ProjectInfo去除

this.HasRequired(pr => pr.InputPerson)
             .WithMany()
             .HasForeignKey(pr => pr.InputPersonId);
 public partial class ProjectInputPersonMap : EntityTypeConfiguration<ProjectInputPerson>
    {
        public ProjectInputPersonMap()
        {
            this.ToTable("ProjectInputPerson");
            this.HasKey(pc => pc.Id);

            this.HasRequired(pc => pc.ProjectInfo)
                .WithOptional(p => p.InputPerson);

            this.HasRequired(pc => pc.User)
                .WithMany()
                .HasForeignKey(pc => pc.UserId);
        }
    }

 

如有描述不對的地方,請在評論中指出。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM