首页 > 解决方案 > 实体框架:WillCascadeOnDelete 和 Include

问题描述

我有一个这样的数据库模型:

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

表的 sqldbo.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 server profiler 中看到当我执行时:

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

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

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

标签: c#sql-serverentity-framework

解决方案


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

EF Core 模型中配置的删除行为仅在使用 EF Core 删除主体实体并将依赖实体加载到内存中(即,用于跟踪的依赖项)时应用。需要在数据库中设置相应的级联行为,以确保上下文未跟踪的数据应用了必要的操作。如果您使用 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();

推荐阅读