繁体   English   中英

实体框架核心 - 无法跟踪实体类型的实例,因为已在跟踪具有相同键的此类型的另一个实例

[英]Entity Framework core - The instance of entity type cannot be tracked because another instance of this type with the same key is already being tracked

我目前正在尝试使用 .net 核心和 EF 核心。

我有以下代码来更新数据

protected void Update(T entity, bool saveChanges = true)
{
    _context.Set<T>().Attach(entity);
    _context.Entry(entity).State = EntityState.Modified;
    if (saveChanges) _context.SaveChanges();
}

我正在更新的课程

public partial class Blog
{
    public Blog()
    {
        Post = new HashSet<Post>();
    }

    public int BlogId { get; set; }
    public string Url { get; set; }

    public virtual ICollection<Post> Post { get; set; }
}

当我第一次尝试更新任何条目时,它成功了。 第二次更新同一条目时,出现以下错误:

System.InvalidOperationException: '无法跟踪实体类型 'Blog' 的实例,因为已在跟踪具有相同键的此类型的另一个实例。 添加新实体时,对于大多数键类型,如果未设置键(即,如果键属性为其类型分配了默认值),将创建一个唯一的临时键值。 如果您为新实体显式设置键值,请确保它们不会与现有实体或为其他新实体生成的临时值发生冲突。 附加现有实体时,确保只有一个具有给定键值的实体实例附加到上下文。

每个条目都会发生同样的情况,第一次成功,第二次失败。

附加信息:我使用以下代码获取所有数据:

protected IEnumerable<T> GetAll()
{
    return _context.Set<T>().AsNoTracking().AsEnumerable();
}

在视图中以表格形式显示以上内容。 DTO 用于在数据层和 Web 层之间进行通信。

上下文在启动时注册如下

services.AddDbContext<BloggingContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

我的问题是为什么在第二次更新期间出现错误以及如何解决它。 谢谢。

你的服务提供者是静态的,所以它实际上是一个单例。 正如这里所建议的github.com/aspnet/EntityFramework/issues/2652

该异常意味着您正在尝试将具有相同键的两个实体实例附加到上下文。 当在启动时注入存储库的单例实例时,就会发生这种情况。

我建议将您的通用存储库从抽象类更改为接口,并在启动期间注入正确的存储库:

services.AddScoped<IRepository<Blog>, BlogRepository>();
services.AddScoped<IRepository<Post>, PostRepository>();

而不是您的静态 ServiceProvider,它实际上提供了您的 BlogRepository 的单例实现

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM