System.ObjectDisposedException:无法访问已释放的对象
问题描述:
我有以下GenericRepository: -System.ObjectDisposedException:无法访问已释放的对象
public class GenericRepository<T> : IGenericRepository<T> where T : class
{
public readonly SportsStore2Context Context;
protected DbSet<T> DbSet;
public GenericRepository(SportsStore2Context context)
{
Context = context;
DbSet = context.Set<T>();
}
public async Task<T> Get<TKey>(Expression<Func<T, bool>> filter = null, string includeProperties = "")
{
IQueryable<T> query = Context.Set<T>();
query = IncludePropertiesQuery(query, includeProperties);
if (filter != null)
{
query = query.Where(filter);
}
return await query.SingleOrDefaultAsync();
}
public async Task<List<T>> GetAll(Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, string includeProperties = "")
{
IQueryable<T> query = Context.Set<T>();
query = IncludePropertiesQuery(query, includeProperties);
if (orderBy != null)
{
query = orderBy(query);
}
var collection = await query.ToListAsync();
return collection;
}
public async Task Add(T entity, Expression<Func<T, bool>> filter = null)
{
var existing = await Get<T>(filter);
if (existing == null)
{
Context.Set<T>().Add(entity);
Save();
}
}
public void Update(T entity)
{
Context.Set<T>().Update(entity);
Save();
}
public void Delete(T entity)
{
var dbSet = Context.Set<T>();
if (Context.Entry(entity).State == EntityState.Detached)
{
dbSet.Attach(entity);
}
dbSet.Remove(entity);
Save();
}
private void Save()
{
try
{
Context.SaveChanges();
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
private IQueryable<T> IncludePropertiesQuery(IQueryable<T> query, string includeProperties = "")
{
includeProperties = includeProperties.Trim() ?? string.Empty;
foreach (var includeProperty in includeProperties.Split
(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
return query;
}
}
GET和GETALL工作正常,但是当我尝试的东西添加到数据库中,我得到一个“系统.ObjectDisposedException:无法访问处置对象“错误。
我已经宣布了库作为启动的配置如下: -
services.AddScoped(typeof(IGenericRepository<>), typeof(GenericRepository<>));
可能是什么问题呢?我是否错误地声明了上下文?
感谢您的帮助和时间。
UPDATE
卸下的await(异步)不正常工作
public void Add(T entity, Expression<Func<T, bool>> filter = null)
{
var existing = Get<T>(filter);
if (existing.Result != null) return;
Context.Add(entity);
Save();
}
这是正确的吗?
答
(我不知道这个特定的类但这是混合异步和非异步代码一般建议)
还有就是为什么我们建议异步函数遵循命名模式MyFuncAsync一个很好的理由,那是因为当您尝试从非异步函数调用异步函数时,它可以很容易地看到。
从您的意见拉了这一点,这就是你怎么骂添加
public bool Add(T entity, Expression<Func<T, bool>> filter = null)
{
try
{
genericRepository.Add(entity, filter);
}
catch (Exception e)
{
return false;
}
return true;
}
但你从非异步一个(这将是比较明显的这里调用一个异步函数,如果函数被调用AddAsync),这将导致问题,除非你阻止非异步函数是这样的:
public bool Add(T entity, Expression<Func<T, bool>> filter = null)
{
try
{
genericRepository.Add(entity, filter).Wait();
}
catch (Exception e)
{
return false;
}
return true;
}
这是更好的,如果它是异步的所有方式,因为当操作完成这个线程将阻塞,但这应该工作。
由于您将上下文传递给构造函数,有可能将它置于其他位置?一般来说,创建和处理要采取的每个原子动作的上下文会更好。 – juharr
因此,而不是像我以前那样在构造函数中传递它,我应该在每种方法中使用它? – Johann
尝试使用(var context = new SportsStore2Context(new DbContextOptions())) 既Get和Add也不工作obv因为正在实例化新的上下文 –
Johann