实体框架:如何解决“外键约束可能会导致循环或多个级联路径”?(Entity Framework: h

2019-07-18 15:13发布

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

我有一个Office ,其具有一对多的关系表DoctorSecretary台。 二者最后的表,衍生自Employee具有带有预定义的一个共享主键关系表Users通过创建的表sqlmembershipprovider 。 似乎有之间的多对多关系, Users表和Roles表,我没有任何的手在里面。

我的问题是在创造一个(零一) -我之间(一个)关系Employee表和Users表,我与他们提出,那么误差之间的共享主键关系结束。 (有没有这个问题更好的解决方案?)

这里是错误:

将外键约束“FK_dbo.aspnet_UsersInRoles_dbo.aspnet_Users_UserId”上表“aspnet_UsersInRoles”可能会导致循环或多个级联路径。 指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他外键约束。 无法创建约束。 请参阅以前的错误。

这里有逆向工程后,我的代码和代码的成员:

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了。

Answer 1:

您可以使用流利的API指定的错误信息提示的行动。

在上下文:

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

需要注意的是,你还没有为表aspnet_UsersInRoles定义所以这段代码可能无法正常工作。

另一种选择是加入这个删除所有级联删除

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

如果您需要了解与流畅API配置关系的更多信息,我建议http://msdn.microsoft.com/en-US/data/jj591620



Answer 2:

您还可以修改您的迁移类。 在我的移民类案件是:

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:真正的”更新的数据库的完美的作品。

或为false

 .ForeignKey("dbo.Categories", t => t.CategoryId, cascadeDelete: false)


Answer 3:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
    }

在上下文中添加该代码



Answer 4:

根据您的意见,问题是,你两个表中使用相同的PK。 我想改变这种状况的时候了,让用户PK为员工提供一个FK关系到用户(一对一我猜)的额外字段。 并增加一个独立的PK给用户(另一GUID,尊重你的表的其余部分)。 如果你想保证在员工(指向用户的)新的外键是唯一的,你可以随时添加一个唯一索引。

你把你的结构都是相同的,你摆脱周期的方式。



Answer 5:

只是一个更新

至于其他的答案建议你要不做就删除任何行动。 这样的更新方式为核心的EntityFramework 1.0如下

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

注意:不要ReferentialAction.NoActiononDelete



文章来源: Entity Framework: how to solve “FOREIGN KEY constraint may cause cycles or multiple cascade paths”?