实体框架:WillCascadeOnDelete和包含

时间:2020-05-07 09:27:16

标签: c# sql-server entity-framework

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

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的sql如下:

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将在删除用户之前分别删除所有订单。我以为EF在设置ON DELETE CASCADE时依赖于SQL Server外键中指定的WillCascadeOnDelete(true)(这是EF中关系的默认行为)。

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

1 个答案:

答案 0 :(得分:0)

如果您在变更跟踪器中加载了从属实体,则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();