加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

sql-server – 引入FOREIGN KEY约束可能会导致循环或多个级联路

发布时间:2020-12-12 16:56:36 所属栏目:MsSql教程 来源:网络整理
导读:用户,雇主,候选人和工作,雇主可以创建多个工作,每个工作只能有一个雇主,候选人可以申请许多工作,每个工作可以有多个应用成员. 所以关系是这样的: 我正在使用实体框架代码第一种方法,目前如果我删除雇主,它将从数据库中删除所有相关的作业和用户,如果我删除候
用户,雇主,候选人和工作,雇主可以创建多个工作,每个工作只能有一个雇主,候选人可以申请许多工作,每个工作可以有多个应用成员.

所以关系是这样的:

我正在使用实体框架代码第一种方法,目前如果我删除雇主,它将从数据库中删除所有相关的作业和用户,如果我删除候选人,它将删除用户:

modelBuilder.Entity<Employer>()
     .HasRequired(e => e.User)
    .WithOptional(e => e.Employer).WillCascadeOnDelete();

//member is candidate
modelBuilder.Entity<Member>()
    .HasRequired(e => e.User)
    .WithOptional(e => e.Member).WillCascadeOnDelete();

modelBuilder.Entity<Employer>()
    .HasMany(a => a.Jobs)
    .WithRequired(b => b.Employer)
    .WillCascadeOnDelete();

一切工作正常,除非我指定候选人和作业之间的多对多关系,并使用“update-database”更新数据库,它给我这个错误:

在表’MemberJobMap’上引入FOREIGN KEY约束’FK_dbo.MemberJobMap_dbo.Jobs_JobId’可能会导致循环或多个级联路径.指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束.
无法创建约束.查看以前的错误.

这是我如何指定多对多的关系:

modelBuilder.Entity<Member>()
   .HasMany(m => m.Jobs)
   .WithMany(j => j.Members)
   .Map(c =>
   {
      c.MapLeftKey("Id");
      c.MapRightKey("JobId");
      c.ToTable("MemberJobMap");
   });

当我添加迁移时

CreateTable(
   "dbo.MemberJobMap",c => new
   {
      Id = c.String(nullable: false,maxLength: 128),JobId = c.Int(nullable: false),})
   .PrimaryKey(t => new { t.Id,t.JobId })
   .ForeignKey("dbo.Members",t => t.Id,cascadeDelete: true)
   .ForeignKey("dbo.Jobs",t => t.JobId,cascadeDelete: true)
   .Index(t => t.Id)
   .Index(t => t.JobId);

我尝试将cascadeDelete更改为false,但是当我删除已经应用作业的候选人或当我尝试使用应用的候选项删除作业时,这会给我错误.

如何解决这个错误?以便:

>当作业被删除时,它将删除关联的
candidatejobmap表行不影响任何其他表
>当候选人被删除时,它将删除关联的
candidatejobmap表行和用户表行不影响任何
其他表
>保持所有其他指定的级联删除操作
一样

解决方法

我已经解决了这个问题

出现此问题是因为我有两个级联删除路径到CandidateJobMap表:

如果我删除雇主,它将删除相关的雇主工作,这将反过来删除CandidateJobMap表:

雇主 – > Jobs-> CandidateJobMap

如果我删除候选人,它将删除CandidateJobMap表:

成员 – > CandidateJobMap

所以要解决这个问题,我必须禁用一个删除路径,当你创建多??对多的关系时,你不能指定WillCascadeDelete(false),所以你必须改变迁移如下:

CreateTable(
   "dbo.MemberJobMap",cascadeDelete: false) <--------cascade delete to false
   .ForeignKey("dbo.Jobs",cascadeDelete: true)
   .Index(t => t.Id)
   .Index(t => t.JobId);

现在因为将级联删除设置为false,候选人已被删除后,将不会删除相关的CandidateJobMap行,当您尝试删除候选项时,它也会导致另一个错误,它也是CandidateJobMap中的相关键,因此您有在删除候选人之前手动删除CandidateJobMap中的相关行:

//remove all applied jobs from user,without doing this,you will receive an error
foreach (var appliedjob in user.Member.Jobs.ToList())
{
    user.Member.Jobs.Remove(appliedjob);
}

//before you can delete the user
await UserManager.DeleteAsync(user);

不知道这是否是最好的方法,但它对我有用.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读