我目前正在尝试使用.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")));
我的问题是为什么在第二次更新期间出现错误以及如何解决它 . 谢谢 .
1 回答
您的服务提供商是静态的,因此它实际上是一个单身人士 . 正如这里建议github.com/aspnet/EntityFramework/issues/2652
该异常意味着您尝试将具有相同键的两个实体实例附加到上下文 . 在启动时注入存储库的单例实例时会发生这种情况 .
我建议将通用存储库从抽象类更改为接口,并在启动期间注入正确的存储库:
而不是静态的ServiceProvider,它实际上提供了BlogRepository的单例实现