37

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

我有一张与和表Office有一对多关系的表。最后两个表都派生自与创建的预定义表具有共享主键关系的表。似乎table 和table之间存在多对多的关系,我没有参与其中。DoctorSecretaryEmployeeUserssqlmembershipproviderUsersRoles

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; }
}

编辑:Users关系更深入,表和表之间存在多对一的关系Applications,也存在于Roles和之间Applications

4

5 回答 5

67

您可以使用 fluent api 指定错误消息建议的操作。

在您的上下文中:

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

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

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

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

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

于 2013-01-24T03:44:47.207 回答
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)
于 2014-08-26T19:28:35.823 回答
7
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
    }

在上下文中添加此代码

于 2015-02-10T07:47:48.300 回答
3

根据您的评论,问题在于您在两个表中使用相同的 PK。我会立即改变这一点,将用户 PK 作为员工中的一个额外字段,与用户有 FK 关系(我猜是一对一)。并为用户添加一个独立的 PK(另一个尊重您的表格的指南)。如果要保证Employees 中的新外键(指向Users 的外键)是唯一的,可以随时添加唯一索引。

这样你就可以保持你的结构不变并且你摆脱了循环。

于 2013-01-24T15:30:09.543 回答
2

只是一个更新

正如其他答案所暗示的,您无需对删除执行任何操作。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

于 2017-09-19T18:00:04.523 回答