关于这个问题有很多问题,但我无法解决我的问题。 有人可以看看这个:
我有一个Office
表,它与Doctor
和Secretary
表有一对多的关系。两个最后的表都派生自Employee
表,该表与Users
创建的预定义sqlmembershipprovider
表具有共享主键关系。似乎Users
表和Roles
表之间有很多关系,我没有参与其中。
我的问题是在我的Employee
表和Users
表之间建立一个(零,一) - (一)关系,我以它们之间的共享主键关系结束,并且引发了错误, 然后。 (这个问题有更好的解决方案吗?)
这是错误:
引入FOREIGN KEY约束 桌上的'FK_dbo.aspnet_UsersInRoles_dbo.aspnet_Users_UserId' 'aspnet_UsersInRoles'可能会导致循环或多个级联路径。 指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他 FOREIGN KEY约束。无法创建约束。见前 错误。
以下是逆向工程后的代码和会员代码:
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
和{{之间也存在多个关系1}}。
答案 0 :(得分:66)
您可以使用流畅的api指定错误消息建议的操作。
在您的上下文中:
protected override void OnModelCreating( DbModelBuilder modelBuilder )
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<aspnet_UsersInRoles>().HasMany(i => i.Users).WithRequired().WillCascadeOnDelete(false);
}
请注意,您尚未包含表aspnet_UsersInRoles的定义,因此此代码可能无效。
另一种选择是通过添加此
来删除所有CASCADE DELETESmodelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
如果您需要有关配置与流畅api的关系的更多信息,我建议http://msdn.microsoft.com/en-US/data/jj591620
答案 1 :(得分:21)
您也可以修改迁移类。在我的案例中,迁移类是:
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”后,Update-Database工作正常。
或false
.ForeignKey("dbo.Categories", t => t.CategoryId, cascadeDelete: false)
答案 2 :(得分:7)
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
}
在上下文中添加此代码
答案 3 :(得分:3)
根据您的评论,问题是您在两个表中使用相同的PK。 我马上改变了,将用户PK作为雇员中的一个额外字段,与用户建立FK关系(我猜是一对一)。并为用户添加一个独立的PK(另一个guid来尊重你的其余表)。如果要保证Employees中的新外键(指向用户的外键)是唯一的,您始终可以添加唯一索引。
这样你就可以保持你的结构完全相同,你就可以摆脱这种循环。
答案 4 :(得分:1)
只需更新:
正如其他答案所示,您不需要对删除做任何操作。对于Entityframework Core 1.0
,更新的方法如下table.ForeignKey(name: "FK_Cities_Regions_RegionId",
column: x => x.RegionId,
principalTable: "Regions",
principalColumn: "RegionId",
onDelete: ReferentialAction.NoAction);
注意:ReferentialAction.NoAction
上的onDelete