实体框架代码首先:多对多(> = 3)

时间:2013-11-25 21:35:49

标签: .net ef-code-first many-to-many entity-framework-6

我试图通过引入第四个表来建立三个表的关系,就像在SQL中一样 但是当我运行'update-database'时会发生错误:'FK ... dbo.ProjectUsersRoles User Id导致循环或多个级联路径'。 我尝试过属性和Fluent Api,但结果是一样的 - 错误。也许有人有类似的错误或问题。这是代码:

public class Project
{
   [Key]
   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   public int Id { get; set; }

   public virtual ICollection<ProjectUserRole> UsersRoles { get; set; }
}
public class User
{
   [Key]
   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   public int Id { get; set; }

   public virtual ICollection<ProjectUserRole> RolesOnProject { get; set; }
}
public class Role
{
   [Key]
   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   public int Id { get; set; }

   public virtual ICollection<ProjectUserRole> UsersProjects { get; set; }
}
public class ProjectUserRole
{
   [Key]
   public int UserId { get; set; }
   [Key]
   public int ProjectId { get; set; }
   [Key]
   public int RoleId { get; set; }


   public User User { get; set; }

   public Project Project { get; set; }

   public Role Role { get; set; }
}

非常感谢你的帮助!

3 个答案:

答案 0 :(得分:1)

您是否尝试过指定cascadeOnDelete属性? 您必须使用流畅的配置执行此操作,例如:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

        modelBuilder.Entity<User>()
            .HasMany(u => u.RolesOnProject).WithRequired()
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Project>()
            .HasMany(u => u.UsersRoles).WithRequired()
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Role>()
            .HasMany(u => u.UsersProjects).WithRequired()
            .WillCascadeOnDelete(false);

    }

此方法应该在您的DbContext类中。如你所见,我将所有这些设置为不在删除时级联。你将不得不玩这个,让它做你想要的。

-------的 *** *** EDIT ------

我没有对此进行过测试,但是如果你想在删除项目时进行级联删除,我相信这将是配置。但是,您可以考虑手动处理级联删除。

   protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

        modelBuilder.Entity<User>()
            .HasMany(u => u.RolesOnProject).WithRequired()
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Project>()
            .HasMany(u => u.UsersRoles).WithRequired()
            .WillCascadeOnDelete(true); // Changed this..

        modelBuilder.Entity<Role>()
            .HasMany(u => u.UsersProjects).WithRequired()
            .WillCascadeOnDelete(false);

    }

答案 1 :(得分:1)

抱歉,我误解了你的删除方向。

我只想添加一个警告。请注意,现在执行删除操作可能会在数据库中留下不可用的数据。示例:如果用户要求RolesOnProjects列表中的项目在应用程序中可用。删除级联删除用户所需的ProjectUserRole的角色将使用户无效(因为RolesOnProjectList现在为空)。这对你来说可能不是问题,但请记住这一点。

(我暂时不允许添加评论(没有50个代表)所以我会在这里回答。)

答案 2 :(得分:0)

刚刚朝另一个方向发展

modelBuilder.Entity<ProjectUserRole>()
            .HasRequired(x => x.Project)
            .WithMany(x => x.UsersRoles)
            .HasForeignKey(x => x.ProjectId)
            .WillCascadeOnDelete(true);
        modelBuilder.Entity<ProjectUserRole>()
            .HasRequired(x => x.User)
            .WithMany(x => x.RolesOnProjects)
            .HasForeignKey(x => x.UserId)
            .WillCascadeOnDelete(true);
        modelBuilder.Entity<ProjectUserRole>()
            .HasRequired(x => x.Role)
            .WithMany(x => x.ProjectsUsers)
            .HasForeignKey(x => x.RoleId)
            .WillCascadeOnDelete(true);
希望这会对某人有所帮助。 WillDeleteOnCascade指向linking

问题也可能在级联链中的多个相同表中(表可能只在级联链中出现一次 - 这不是代码优先,而是MSSQL问题)