我正在尝试实现异步存储库模式并希望异步更新:
我的 Controller 如下所示:
// PUT api/category
[HttpPut]
public void Put([FromBody] CategoryDto categoryDto)
{
var category = _mapper.Map<Categories>(categoryDto);
_categoryService.UpdateCategory(category);
}
我的RepositotyBase<T>
类:
public abstract class RepositoryBase<T> where T : class
{
public virtual async Task Update(T entity)
{
// This code throws error: Cannot access a disposed object. A common
// cause of this error is disposing ...
await Task.Run(() => { // I have **await** here
dbSet.Attach(entity);
shopContext.Entry(entity).State = EntityState.Modified;
});
}
}
我的CategoryService
:
public class CategoryService : ICategoryService
{
public async Task UpdateCategory(Categories category)
{
await _categoryRepository.Update(category); // I have **await** here
_unitOfWork.Commit();
return;
}
}
但是,方法 public virtual async Task Update(T entity)
的异步实现的RepositoryBase<T>
抛出错误:
public abstract class RepositoryBase<T> where T : class
{
public virtual async Task Update(T entity)
{
// This code throws error: Cannot access a disposed object. A common
// cause of this error is disposing ...
await Task.Run(() => {
dbSet.Attach(entity); // I have **await** here
shopContext.Entry(entity).State = EntityState.Modified;
});
}
}
Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
更新: 这是正确的异步实现吗?
我的 Controller :
// PUT api/category
[HttpPut]
public void Put([FromBody] CategoryDto categoryDto)
{
var category = _mapper.Map<Categories>(categoryDto);
_categoryService.UpdateCategory(category);
}
我的通用存储库:
public abstract class RepositoryBase<T> where T : class
{
public virtual async Task Update(T entity)
{
dbSet.Attach(entity);
shopContext.Entry(entity).State = EntityState.Modified;
}
}
我的工作单位:
public class UnitOfWork : IUnitOfWork
{
private readonly IDbFactory dbFactory;
private StoreEntities dbContext;
public UnitOfWork(IDbFactory dbFactory)
{
this.dbFactory = dbFactory;
}
public StoreEntities DbContext
{
get { return dbContext ?? (dbContext = dbFactory.Init()); }
}
public async Task CommitAsync()
{
//DbContext.Commit();
await DbContext.SaveChangesAsync();
}
}
我的服务:
public class CategoryService : ICategoryService
{
public async Task UpdateCategory(Categories category)
{
_categoryRepository.Update(category); // I have **await** here
await Task.Run(()=> {_unitOfWork.Commit()}); //
return;
}
}
最佳答案
您需要将 Controller 操作 PUT api/category
设置为异步/等待感知。
@mjwills 在评论中提到了这一点。
// PUT api/category
[HttpPut]
public async Task Put([FromBody] CategoryDto categoryDto)
{
var category = _mapper.Map<Categories>(categoryDto);
await _categoryService.UpdateCategory(category);
// you probably want to set a response code. e.g return OK()
}
这有点离题,但我正在讨论其他一些评论。
您还需要将更改保存到 EF 中的数据库。您不需要手动创建自己的任务。据我所知,EF 为您提供了一个 SaveChangesAsync
方法:https://learn.microsoft.com/en-us/ef/core/saving/async .
public abstract class RepositoryBase<T> where T : class
{
public virtual async Task Update(T entity)
{
dbSet.Attach(entity);
shopContext.Entry(entity).State = EntityState.Modified;
await shopContext.SaveChangesAsync();
}
}
public class CategoryService : ICategoryService
{
public async Task UpdateCategory(Categories category)
{
return await _categoryRepository.Update(category);
}
}
关于c# - 使用异步存储库模式 - 无法访问已处置的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57952486/