entity framework:如何解决“FOREIGN KEY约束可能导致周期或多个级联path”?

关于这个问题有很多问题,但我解决不了我的情况。 有人可以看看这个:

我有一张与DoctorSecretary桌有一对多关系的Doctor 。 最后一个表都是从Employee表派生而来的,该表与sqlmembershipprovider创build的预定义Users表具有共享主键关系。 Users表和Roles表之间似乎有许多关系,我没有任何关系。

我的问题是在我的Employee表和Users表之间创build一个(零,一) – (一)关系,然后我们以它们之间的共享主键关系和引发的错误结束。 (这个问题有更好的解决方法吗?)

这里是错误的:

引入表“aspnet_UsersInRoles”上的FOREIGN KEY约束“FK_dbo.aspnet_UsersInRoles_dbo.aspnet_Users_UserId”可能会导致循环或多个级联path。 指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。 无法创build约束。 查看以前的错误。

这里是我的代码和反向工程后的会员代码:

 public class Office { public Office() { this.Doctors = new HashSet<Doctor>(); this.Secretaries = new HashSet<Secretary>(); } [Key] public System.Guid OfficeId { get; set; } public virtual ICollection<Doctor> Doctors { get; set; } public virtual ICollection<Secretary> Secretaries { get; set; } } public class Employee { [Key, ForeignKey("User")] [DatabaseGenerated(DatabaseGeneratedOption.None)] public System.Guid Id { get; set; } public string Name { get; set; } [ForeignKey("Office")] public System.Guid OfficeId { get; set; } // shared primary key public virtual aspnet_Users User { get; set; } public virtual Office Office { get; set; } } public class Doctor :Employee { public Doctor() { this.Expertises = new HashSet<Expertise>(); } //the rest.. public virtual ICollection<Expertise> Expertises { get; set; } } public class Secretary : Employee { // blah blah } public class aspnet_Users { public aspnet_Users() { this.aspnet_Roles = new List<aspnet_Roles>(); } public System.Guid ApplicationId { get; set; } public System.Guid UserId { get; set; } //the rest.. public virtual aspnet_Applications aspnet_Applications { get; set; } public virtual ICollection<aspnet_Roles> aspnet_Roles { get; set; } } public class aspnet_Roles { public aspnet_Roles() { this.aspnet_Users = new List<aspnet_Users>(); } public System.Guid ApplicationId { get; set; } public System.Guid RoleId { get; set; } //the rest.. public virtual aspnet_Applications aspnet_Applications { get; set; } public virtual ICollection<aspnet_Users> aspnet_Users { get; set; } } 

编辑:和关系变得更深, Users表和Applications表之间,还有RolesApplications之间的许多关系。

您可以使用stream利的api来指定错误消息build议的操作。

在你的上下文中:

 protected override void OnModelCreating( DbModelBuilder modelBuilder ) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<aspnet_UsersInRoles>().HasMany(i => i.Users).WithRequired().WillCascadeOnDelete(false); } 

请注意,您尚未包含表aspnet_UsersInRoles的定义,因此此代码可能不起作用。

另一个select是删除所有CASCADE DELETESjoin这个

 modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); 

如果你需要更多关于configurationstream利api的关系的信息,我build议http://msdn.microsoft.com/en-US/data/jj591620

你也可以修改你的移植课程。 在我的情况下,在移民课是:

 CreateTable( "dbo.Spendings", c => new { SpendingId = c.Int(nullable: false, identity: true), CategoryGroupId = c.Int(nullable: false), CategoryId = c.Int(nullable: false), Sum = c.Single(nullable: false), Date = c.DateTime(nullable: false), Comment = c.String(), UserId = c.String(), LastUpdate = c.String(), }) .PrimaryKey(t => t.SpendingId) .ForeignKey("dbo.Categories", t => t.CategoryId, cascadeDelete: true) .ForeignKey("dbo.CategoryGroups", t => t.CategoryGroupId, cascadeDelete: true) .Index(t => t.CategoryGroupId) .Index(t => t.CategoryId); 

删除“cascadeDelete:true”后,更新数据库完美工作。

或者是false

  .ForeignKey("dbo.Categories", t => t.CategoryId, cascadeDelete: false) 
  protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); } 

在上下文中添加此代码

根据你的意见,问题是你在这两个表中使用相同的PK。 我会立即改变这种情况,将用户PK作为员工中的一个额外字段,与用户build立FK关系(我猜想是一对一的)。 并添加一个独立的PK给用户(另一个GUID尊重你的其余表)。 如果要确保Employees中的新外键(指向用户的外键)是唯一的,则始终可以添加唯一索引。

这样你保持你的结构一样,你摆脱了循环。

只是一个更新

正如其他答案build议你不需要做任何删除操作。 更新方式如下Entityframework Core 1.0

 table.ForeignKey(name: "FK_Cities_Regions_RegionId", column: x => x.RegionId, principalTable: "Regions", principalColumn: "RegionId", onDelete: ReferentialAction.NoAction); 

注意:对onDelete执行ReferentialAction.NoAction