【发布时间】:2019-05-15 01:37:14
【问题描述】:
我已经看到并且我确信在 EF Core 中使用了这种技术,通过创建存根对象来删除记录以保存到数据库的行程,但是使用这种方法不会向数据库发送删除。有谁知道为什么?
public void DeleteById(int blogPostId)
{
// Does not work
// Use Stub to save extra db trip
/*
var blogPost = new BlogPost { Id = blogPostId };
_context.Entry(blogPost).State = EntityState.Deleted;
_context.BlogPosts.Remove(blogPost);
_context.SaveChanges();
*/
// Works
var blogPost = _context.BlogPosts.Find(blogPostId);
_context.Entry(blogPost).State = EntityState.Deleted;
_context.BlogPosts.Remove(blogPost);
_context.SaveChanges();
}
作为一个附加问题,直接在上下文或 DbSet 上使用 remove 有什么区别,因为两者都可以正常工作?
_context.Remove(blogPost);
_context.BlogPosts.Remove(blogPost);
如果我将代码更改为以下:
public void DeleteById(int blogPostId)
{
// Does not work
// Use Stub to save extra db trip
var blogPost = new BlogPost { Id = blogPostId };
//_context.Entry(blogPost).State = EntityState.Deleted;
_context.BlogPosts.Remove(blogPost);
_context.SaveChanges();
// Works
//var blogPost = _context.BlogPosts.Find(blogPostId);
//_context.Entry(blogPost).State = EntityState.Deleted;
//_context.BlogPosts.Remove(blogPost);
//_context.SaveChanges();
}
我收到以下错误:
An unhandled exception has occurred while executing the request.
System.InvalidOperationException:无法跟踪实体类型“BlogPost”的实例,因为已经在跟踪具有相同键值 {'Id'} 的另一个实例。附加现有实体时,请确保仅附加一个具有给定键值的实体实例。考虑使用“DbContextOptionsBuilder.EnableSensitiveDataLogging”来查看冲突的键值。
【问题讨论】:
-
您不需要在条目上设置
State。调用_context.Remove(blogPost)会将实体添加到跟踪更改机制并将其(和相关实体)状态设置为已删除。 -
根据您的第一个示例不工作,这很奇怪,因为它应该工作。这是你的真实代码,还是只是它的简化?
-
这是完整的代码,因为它是一个演示问题的测试。如果我没有将状态设置为已删除,则会收到我在帖子中更新的错误。