简体   繁体   English

System.ObjectDisposedException:无法访问已处置的对象

[英]System.ObjectDisposedException: Cannot access a disposed object

I have the following GenericRepository:- 我有以下GenericRepository:

    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;

    }

}

The Get and GetAll work fine, however when I try to Add something to the database, I am getting a "System.ObjectDisposedException: Cannot access a disposed object" error. Get和GetAll工作正常,但是,当我尝试向数据库中添加内容时,出现“ System.ObjectDisposedException:无法访问已处置的对象”错误。

I have declared the repository as follows in the Configure of the Startup:- 我已经在“启动配置”中声明了存储库,如下所示:

   services.AddScoped(typeof(IGenericRepository<>), typeof(GenericRepository<>));

What could be the problem? 可能是什么问题呢? Am I declaring the context erroneously? 我是在错误地声明上下文吗?

Thanks for your help and time. 感谢您的帮助和时间。

UPDATE UPDATE

Removing the await(async) does work correctly 删除await(async)可以正常工作

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

Is this correct? 这个对吗?

(I don't know this particular class but this is general advice for mixing async and non-async code) (我不知道这个特定的类,但这是混合异步和非异步代码的一般建议)

There's a good reason why it's recommended that async functions follow the naming pattern MyFuncAsync, and that's because it makes it easy to see when you try to call an async function from a non-async one. 建议使用异步函数遵循命名模式MyFuncAsync是有充分理由的,这是因为当您尝试从非异步函数调用异步函数时,它很容易看到。

Pulling this out from your comments, this is how you call Add 从您的评论中删除,这就是您所说的添加

public bool Add(T entity, Expression<Func<T, bool>> filter = null)
{
    try
    {
        genericRepository.Add(entity, filter);
    }
    catch (Exception e)
    {
       return false;
    }
    return true;
}

But you're calling an async function here from an non-async one (which would be more obvious if the function was called AddAsync), which will cause issues unless you block the non-async function like this: 但是您是在这里从非异步函数中调用异步函数(如果将该函数称为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;
}

It's better if it's async all the way, as this thread will block while the the operation completes, but this should work. 最好一直保持异步状态,因为该线程将在操作完成时阻塞,但这应该可以工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 System.ObjectDisposedException:无法访问Xamarin中的已处置对象 - System.ObjectDisposedException: Cannot access a disposed object in Xamarin System.ObjectDisposedException:无法访问已处置的对象。 AplicationDbContext - System.ObjectDisposedException: Cannot access a disposed object. AplicationDbContext httpclient.postasync - System.ObjectDisposedException:无法访问已处理的对象 - httpclient.postasync - System.ObjectDisposedException: Cannot access a disposed object System.ObjectDisposedException:&#39;无法访问已处置的对象。&#39; - System.ObjectDisposedException: 'Cannot access a disposed object.' .NET 3.5 C#Bug with System.Timer System.ObjectDisposedException:无法访问已处置的对象 - .NET 3.5 C# Bug with System.Timer System.ObjectDisposedException: Cannot access a disposed object System.ObjectDisposedException:&#39;无法访问已处置的对象。对象名称:&#39;OracleConnection&#39;。 - System.ObjectDisposedException: 'Cannot access a disposed object.Object name: 'OracleConnection'.' System.ObjectDisposedException:无法访问已处理的对象。 对象名称:&#39;Syncfusion.ListView.XForms.Android.ExtendedScrollViewRenderer&#39; - System.ObjectDisposedException: Cannot access a disposed object. Object name: 'Syncfusion.ListView.XForms.Android.ExtendedScrollViewRenderer' System.ObjectDisposedException:无法访问已处理的对象,ASP.NET Core 3.1 - System.ObjectDisposedException: Cannot access a disposed object, ASP.NET Core 3.1 System.ObjectDisposedException:无法访问已处置的对象。 -如何检查App是否在Xamarin中运行? - System.ObjectDisposedException: Cannot access a disposed object. - How to check if App is running in Xamarin? Exception on Xamarin: System.ObjectDisposedException: Cannot access a disposed object 'Xamarin.Forms.Platform.Android.FastRenderers.LabelRenderer' - Exception on Xamarin: System.ObjectDisposedException: Cannot access a disposed object 'Xamarin.Forms.Platform.Android.FastRenderers.LabelRenderer'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM