实体框架多级联删除

时间:2015-07-19 18:39:54

标签: c# .net entity-framework ef-migrations

我有三个模型,User,Room和PlayerRoom定义如下:

public class User
{
    public int id { get; set; }
    public string UserName { get; set; }

    //flags user to be deleted when room is no longer available
    public bool temporaryUser { get; set; }

    [JsonIgnore]
    public bool permanent { get; set; }
}

public class Room
{
    public int id { get; set; }
    public string RoomName { get; set; }

    [JsonIgnore]
    public int CreatedById { get; set; }
    public virtual User CreatedBy { get; set; }
}


public class PlayerRoom
{
    public int id { get; set; }

    [JsonIgnore]
    public int RoomId { get; set; }
    public virtual Room Room { get; set; }

    [JsonIgnore]
    public int UserId { get; set; }
    public virtual User User { get; set; }
}

我想要完成的是设置模型,以便在删除User或删除Room时删除所有关联的PlayerRoom。< / p>

目前,当我生成迁移并运行update-database时,我收到错误:

Introducing FOREIGN KEY constraint 'FK_dbo.Rooms_dbo.Users_CreatedById' on table 'Rooms' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

无法创建约束。查看以前的错误。

我所做的研究是因为PlayerRoom可以从级联中以多种方式删除,但这是预期的行为。

如何让迁移工具生成不会引发此错误的迁移?

谢谢!

2 个答案:

答案 0 :(得分:0)

我最后改变了我的类,使它们更具限制性,在这种情况下实际上效果更好。我删除了PlayerRoom对象并将Room引用移动到用户对象上。

public class User
{
    public int id { get; set; }
    public string UserName { get; set; }

    //flags user to be deleted when room is no longer available
    public bool temporaryUser { get; set; }

    public bool? isHost { get; set; }

    [JsonIgnore]
    public int? RoomId { get; set; }
    public virtual Room Room { get; set; }

    [JsonIgnore]
    public bool permanent { get; set; }
}

public class Room
{
    public int id { get; set; }
    public string RoomName { get; set; }
}

通过将Room移动到用户而不是单独的对象上,它会将用户限制为只有一个Room并摆脱我的级联删除问题

答案 1 :(得分:0)

  

摆脱了我的级联删除问题

使用Code First的EF默认设置级联为开启。要从模型中关闭它,可以策略性地将“WillCascadeOnDelete”放置在相关实体之外:

.WillCascadeOnDelete(false);

或全球

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();