我目前正在尝试使用.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:&#39;实体类型的实例&#39; Blog&#39;无法跟踪,因为已经跟踪了具有相同密钥的此类型的另一个实例。添加新实体时,对于大多数密钥类型,如果未设置密钥,则将创建唯一的临时密钥值(即,如果为密钥属性指定了其类型的默认值)。如果要为新实体显式设置键值,请确保它们不会与现有实体或为其他新实体生成的临时值发生冲突。附加现有实体时,请确保只有一个具有给定键值的实体实例附加到上下文。&#39;
每个条目都是如此,第一次成功,第二次失败。
其他信息: 我使用以下代码获取所有数据:
protected IEnumerable<T> GetAll()
{
return _context.Set<T>().AsNoTracking().AsEnumerable();
}
在视图中将上面显示为表格。 DTO正被用于在数据和网络层之间进行通信。
上下文在启动时注册如下
services.AddDbContext<BloggingContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
我的问题是为什么在第二次更新期间出现错误以及如何解决它。感谢。
答案 0 :(得分:0)
您的服务提供商是静态的,因此它实际上是一个单身人士。 如此处所示 github.com/aspnet/EntityFramework/issues/2652
该异常意味着您尝试将具有相同密钥的两个实体实例附加到上下文。在启动时注入存储库的单例实例时会发生这种情况。
我建议将通用存储库从抽象类更改为接口,并在启动期间注入正确的存储库:
services.AddScoped<IRepository<Blog>, BlogRepository>();
services.AddScoped<IRepository<Post>, PostRepository>();
而不是静态的ServiceProvider,它实际上提供了BlogRepository的单例实现