提问人:Mihai Dabiste 提问时间:11/1/2023 最后编辑:marc_sMihai Dabiste 更新时间:11/1/2023 访问量:40
更新实体的 EF Core 问题
EF Core issue with updating an entity
问:
我有一个通用存储库,其中包含以下两种方法:
public virtual async Task<T> GetById(TId id, CancellationToken cancellationToken = default)
{
string key = GetCacheKeyById(id);
return await base.GetFromCache(key,
async () => { return await _dbContext.Set<T>().FindAsync(id); },
cancellationToken: cancellationToken);
}
public virtual void Update(T entity)
{
var key = GetCacheKeyById(_dbContext.GetPrimaryKey<TId>(entity));
_dbContext.Set<T>().Update(entity);
DeleteFromCache(key);
}
当我尝试更新实体时,我遇到了问题。
我的问题是,因为在验证层上,我调用了检索实体的方法,所以它被保存在缓存中。GetById
稍后,在业务层中,我再次调用以获取需要更新的实体,在其上设置一些属性,然后调用 .GetById
Update
这会引发异常,并显示以下消息:
无法跟踪实体类型“entity”的实例,因为已跟踪具有相同 {'Id'} 键值的另一个实例。附加现有实体时,请确保仅附加一个具有给定键值的实体实例。
这似乎很公平,因为我正在更新的实体是从缓存中读取的,而不是被跟踪的实体。
现在我正在考虑向不从缓存中读取并直接从中获取实体添加一个可选参数,这应该为我提供跟踪的实体并且应该有效,但它似乎很丑陋。的作用域是,因此它在验证器和业务层中是同一个实例。GetById
dbContext
dbContext
有没有更好/更清洁的方法来解决这个问题?
答: 暂无答案
评论
GetPrimaryKey
_dbContext.AsNoTracking().GetPrimaryKey<TId>(entity)
FindAsync
return await _dbContext.Set<T>().AsNoTracking().FirstOrDefaultAsync(e => e.Id == id)
ChangeTracker