实体框架:如何解决"FOREIGN KEY约束可能导致循环或多个级联路径"?

Bla*_*azi 35 asp.net entity-framework sqlmembershipprovider

关于这个问题有很多问题,但我无法解决我的问题.有人可以看看这个:

我有一个OfficeDoctorSecretary表有一对多的关系.两个最后的表都是从Employee表中派生的,该Users表与创建的预定义表具有共享主键关系sqlmembershipprovider.Users桌子和Roles桌子之间似乎有很多关系,我没有参与其中.

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

这是错误:

在表'aspnet_UsersInRoles'上引入FOREIGN KEY约束'FK_dbo.aspnet_UsersInRoles_dbo.aspnet_Users_UserId'可能会导致循环或多个级联路径.指定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; }
}
Run Code Online (Sandbox Code Playgroud)

编辑:并且关系更深入,Users表和Applications表之间存在多种关系,也存在于Roles和之间Applications.

Cha*_*les 66

您可以使用流畅的api指定错误消息建议的操作.

在您的上下文中:

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

请注意,您没有包含表aspnet_UsersInRoles的定义,因此此代码可能无效.

另一种选择是通过添加它来删除所有CASCADE DELETES

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
Run Code Online (Sandbox Code Playgroud)

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

  • 注意:如果使用此覆盖方法,请记住调用`base.OnModelCreating(modelBuilder);`,否则将不会设置其他约定默认值.对我来说,这会导致新的错误,例如`EntityType'IdentityUserRole'没有定义键.定义此EntityType的密钥 (3认同)

fee*_*per 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);
Run Code Online (Sandbox Code Playgroud)

删除"cascadeDelete:true"后,Update-Database工作正常.

或者作为 false

 .ForeignKey("dbo.Categories", t => t.CategoryId, cascadeDelete: false)
Run Code Online (Sandbox Code Playgroud)


小智 7

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
    }
Run Code Online (Sandbox Code Playgroud)

在上下文中添加此代码

  • 我想用这个吗?它会产生什么样的负面影响? (3认同)