使用存根对象删除记录

时间:2019-05-12 20:00:22

标签: entity-framework-core

我已经看到了,并且我确信可以通过创建存根对象来保存到db的行程,将该技术与EF Core一起使用来删除记录,但是使用此方法永远不会将删除发送到db。有人知道为什么吗?

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'查看冲突的键值。

1 个答案:

答案 0 :(得分:0)

此答案来自https://launchpad.net/ubuntu/trusty/armhf/chromium-chromedriver/65.0.3325.181-0ubuntu0.14.04.1

如果您确定数据库中存在所有ID,并且上下文不包含(不跟踪)具有相同密钥的其他实体,则可以使用简单的假(存根)实体:

_context.RemoveRange(ids.Select(id => new File { Id = id }));

为避免跟踪实体问题,您可以从我对HERE的回答中使用FindTracked自定义扩展方法,并将其与以上任何方法结合使用。

var existingIds = _context.Files.Where(f => ids.Contains(f.Id)).Select(f => f.Id).ToList();

_context.RemoveRange(
existingIds.Select(id => _context.FindTracked(id) ?? new File { Id = id }));
相关问题