为什么Entity Framework这里不抛出异常呢?

Why doesn't Entity Framework throw an exception here?

看这段代码:

Blog blog = new Blog { Url = "http://blogs.msdn.com/adonet" };
blog.Posts.Add(
     new Post { Title = "Hello World", Content = "I wrote an app using EF Core!" });

db.Add(blog);
db.SaveChanges();

// db.Database.ExecuteSqlRaw("Delete from Blogs"); --> throw exception for Foreign key
//db.Remove(blog); // --> works and doesn't throw exception

db.SaveChanges();

我不明白为什么在删除包含post的博客时,我们会出现外键异常(这是正常的,因为我删除了级联选项)。但是当我做 db.Remove(blog) 时,没有抛出异常,并且博客从数据库中删除了...

编辑:

我会更明确:

我故意将删除行为从 onDelete: ReferentialAction.Cascade 更改为 onDelete: ReferentialAction.Restrict,这就是为什么当我尝试使用 sql 命令删除博客时出现外键异常的原因。

另外,为了简单起见,我删除了所有博客,但在数据库中我只添加了一个博客,指定 id 不会改变任何内容。

您必须将 ID 添加到您的 sql 脚本中。现在您正在删除所有博客,而不仅仅是一个新博客。但是有些帖子可以从其他帖子中获得 BlogId 并且您不能删除它们,在您将外键分配给 null 之前或者如果不可能删除之前的所有帖子。

db.Database.ExecuteSqlRaw("Delete from Blogs where BlogId="+blog.BlogId.ToString()); 

阅读 https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.deletebehavior?view=efcore-5.0

当您删除父实体时,您可以通过多种方式告诉 EF 采取行动。如果您在删除父项时没有看到数据库抛出错误,则 EF 正在后台进行一些修复 - 要么成功删除它首先知道的所有子项,要么通过设置的外键列破坏关系在删除父项之前,先将子项设为空(孤立)

如果您从未专门设置任何行为,那么 EF 的行为将取决于 Post.BlogId 是否可为空。如果不是,那么帖子将被删除。如果是,那么他们将被设置为具有空 BlogId。

如果您在启动配置中找到 UseSqlServer 调用并将对 .LogTo(Console.WriteLine, LogLevel.Information) 的调用链接到它