繁体   English   中英

实体框架:WillCascadeOnDelete 和 Include

[英]Entity Framework: WillCascadeOnDelete and Include

我有一个数据库 model 是这样的:

class User
{
    public int ID { get; set; }
    public string Username { get; set; }
    public virtual ICollection<Order> Orders { get; set; }
}
class Order
{
    public int ID { get; set; }
    public string OrderName { get; set; }
    public virtual User User { get; set; }
}

我的modelBuilder配置如下所示:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<User>().ToTable("Users", "dbo");
    modelBuilder.Entity<User>().HasKey(x => x.ID);
    modelBuilder.Entity<User>().Property(x => x.Username).IsRequired();
    modelBuilder.Entity<User>().HasMany(x => x.Orders).WithRequired(x => x.User).WillCascadeOnDelete(true);

    modelBuilder.Entity<Order>().ToTable("Orders", "dbo");
    modelBuilder.Entity<Order>().HasKey(x => x.ID);
    modelBuilder.Entity<Order>().Property(x => x.OrderName).IsRequired();
    modelBuilder.Entity<Order>().Property(x => x.UserID).IsRequired();
}

表 dbo.Orders 的dbo.Orders看起来像:

CREATE TABLE dbo.Orders (
    ID int NOT NULL PRIMARY KEY IDENTITY(1, 1),
    OrderName nvarchar(256) NOT NULL,
    UserID int NOT NULL,

    CONSTRAINT FK_Orders_Users FOREIGN KEY (UserID) REFERENCES dbo.Users (ID) ON DELETE CASCADE
);

我可以在 sql 服务器分析器中看到,当我执行时:

dbContext.Users.Remove(dbContext.Users.Include(x => x.Orders).First(x => x.ID == 1));

EF 在删除用户之前单独删除所有订单。 我认为 EF 在设置WillCascadeOnDelete(true)时依赖于 SQL 服务器外键中指定的ON DELETE CASCADE (这是 EF 中关系的默认行为)。

为什么 EF 会这样做,我如何告诉 EF 在删除User之前不需要删除Order

您可以使用以下方法删除这些级联删除约定:

//Remove cascade delete conventions 
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();

■ 在上面的示例中,EF 在构建 model 时应用了一组约定(约定适用于您的所有实体),您可以使用 fluent 配置或属性覆盖约定,如下所示:

■ 以下代码配置所需的关系,然后禁用级联删除(仅适用于相关实体):

modelBuilder.Entity<Course>()
    .HasRequired(t => t.Department)
    .WithMany(t => t.Courses)
    .HasForeignKey(d => d.DepartmentId)
    .WillCascadeOnDelete(false);

更新:如果您有受此对流影响的FK相关数据,则可以使用 Nullable FK,如下所示。 上面的代码片段将在数据库中创建一个可为空的DepartmentId列,因为我们使用了Nullable<int>类型( ?Nullable<int>的快捷方式)。

public int? DepartmentId { get; set; }

希望这可以帮助。

如果您在更改跟踪器中加载了相关实体,则 EF 将在 SaveChanges() 中应用级联行为。

EF Core model 中配置的删除行为仅在使用 EF Core 删除主体实体并且在 memory 中加载依赖实体(即,用于跟踪的依赖)时应用。 需要在数据库中设置相应的级联行为,以确保上下文未跟踪的数据应用了必要的操作。 如果您使用 EF Core 创建数据库,则会为您设置此级联行为。

https://docs.microsoft.com/en-us/ef/core/saving/cascade-delete#delete-behaviors

如果你不想这样,那就不要取订单。 相反,只需新建一个存根用户并将其删除。

var stubUser = new User() {ID = 1};
dbContext.Users.Remove(stubUser);
dbContext.SaveChanges();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM