【问题标题】:Entity Framework Multiple Cascading Delete实体框架多重级联删除
【发布时间】:2015-07-19 18:39:54
【问题描述】:

我定义了三个模型,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 都会被删除。

目前,当我生成迁移并运行 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 可以通过多种方式从级联中删除,但这是预期的行为。

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

谢谢!

【问题讨论】:

  • 您是从数据库还是代码优先的方法生成实体?
  • 我先用代码

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


【解决方案1】:

我最终改变了我的课程,使其更具限制性,在这种情况下实际上效果更好。我删除了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 中并摆脱我的级联删除问题

【讨论】:

    【解决方案2】:

    摆脱了我的级联删除问题

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

    .WillCascadeOnDelete(false);
    

    或全局

    modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();   
    

    【讨论】:

    • 感谢您花时间写下答案,但我希望级联删除发生而不是禁用它。
    猜你喜欢
    • 2014-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 2020-03-12
    • 2020-08-27
    相关资源
    最近更新 更多