我有一个这样的数据库模型:
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
?
答案 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();