entity framework:如何解决“FOREIGN KEY约束可能导致周期或多个级联path”?
关于这个问题有很多问题,但我解决不了我的情况。 有人可以看看这个:
我有一张与Doctor
和Secretary
桌有一对多关系的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
表之间,还有Roles
和Applications
之间的许多关系。
您可以使用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