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(); 
    } 

这是正确的吗?

+1

由于您将上下文传递给构造函数,有可能将它置于其他位置?一般来说,创建和处理要采取的每个原子动作的上下文会更好。 – juharr

+0

因此,而不是像我以前那样在构造函数中传递它,我应该在每种方法中使用它? – Johann

+0

尝试使用(var context = new SportsStore2Context(new DbContextOptions ())) 既Get和Add也不工作obv因为正在实例化新的上下文 – Johann

(我不知道这个特定的类但这是混合异步和非异步代码一般建议)

还有就是为什么我们建议异步函数遵循命名模式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; 
} 

这是更好的,如果它是异步的所有方式,因为当操作完成这个线程将阻塞,但这应该工作。