AutofaC语言 检索工作单元的新实例 - "DBcontext has been disposed error"



我有一个批处理作业,该作业正在解析CSV文件并创建和处理记录。在每一行,我必须执行提交,因为我需要创建实体,然后使用创建实体的结果。

由于有成千上万的记录,因此性能很慢,我正在努力提高自己的性能。

我的代码看起来像这样:

var data = ParseExcel(filePath);
Setup();
foreach (var batch in data.Split(20))
{
    foreach (var row in batch)
    {
        try
        {
            ParseRow(row);
        }
        catch (Exception e)
        {
            JobLogger.Error(e, "Failed to parse row. Exception: " + e.Message);
            throw;
        }
    }
    _unitOfWork.Commit();
    _unitOfWork.Dispose();
    _unitOfWork = LifetimeScope.Resolve<Owned<IUnitOfWork>>().Value;
    ClientRepository = LifetimeScope.Resolve<Owned<IEntityBaseRepository<Client>>>().Value;

我的处置方法看起来像这样:

public void Dispose()
{
    _dbContext.Dispose();
    _dbContext = null;
    _dbFactory.Dispose();
    _dbFactory = null;
    GC.SuppressFinalize(this);
}

这里的目的是,在处理每批记录后,我想通过处置它来刷新工作单位,并要求AutoFac生成新实例。

但是,当我将项目添加到我的客户端介绍时,它掉了一个错误:

由于dbcontext是 处置。

我的client repository正在使用看起来像这样的通用存储库类:

public class EntityBaseRepository<T> : IEntityBaseRepository<T> where T : class, IEntityBase, new()
    {
        private DataContext _dataContext;
        #region Properties
        protected IDbFactory DbFactory
        {
            get;
        }
        protected DataContext DbContext => _dataContext ?? (_dataContext = DbFactory.Initialise());
        public EntityBaseRepository(IDbFactory dbFactory)
        {
            DbFactory = dbFactory;
        }
        #endregion

这是我的单位工作的一部分:

public class UnitOfWork : IUnitOfWork, IDisposable
{
    private IDbFactory _dbFactory;
    private DataContext _dbContext;
    public UnitOfWork(IDbFactory dbFactory)
    {
        _dbFactory = dbFactory;
    }
    public DataContext DbContext => _dbContext ?? (_dbContext = _dbFactory.Initialise());
    public void Commit()
    {
        DbContext.Commit();
    }

关于为什么我仍然会遇到此错误的任何想法?

,以确保每批操作后我都会获得我的单位工程的新实例声明,然后我使用AUTOFAC注册并解决这些依赖关系。我的一些服务也取决于单位工程,因此我也必须获得这些依赖性的新实例。

这是一个剪切片段:

foreach (var batch in data.Split(10))
{
    using (var scope = LifetimeScope.BeginLifetimeScope("UnitOfWork", b =>
    {
        b.RegisterType<UnitOfWork>().AsImplementedInterfaces().InstancePerLifetimeScope();
        b.RegisterType<MyService>().AsImplementedInterfaces().PropertiesAutowired().InstancePerLifetimeScope();
        b.RegisterGeneric(typeof(EntityBaseRepository<>)).As(typeof(IEntityBaseRepository<>)).InstancePerLifetimeScope();
    }))
    {
        UnitOfWork = scope.Resolve<IUnitOfWork>();
        MyService = scope.Resolve<IMyService>();
        foreach (var row in batch)
        {
            try
            {
                ParseRow(row);
            }
            catch (Exception e)
            {
                JobLogger.Error(e, "Failed to parse row. Exception: " + e.Message);
                throw;
            }
        }
    }
}

在上面的代码中,我给嵌套的寿命范围命名了" unitofwork"的名称。

使用此代码,作业的性能显着提高,因为这次我没有重复使用相同的单位操作实例,该实例正在跟踪数以万计的更改,因为它处理了文件。

此外,我停止将数据分成10的批次 - 我决定在处理每行之后取回新的单位工程,而每行已经涉及将数据插入至少10个不同的表中。

相关内容

最新更新