EF6 DBContext(多个db),工作单元,存储库,Autofac IOC依赖项

时间:2018-10-17 10:25:52

标签: entity-framework-6 autofac

我正在.net Web Api应用程序中使用Ef6。 这是一个遗留的整体,我们正在尝试将其转换为微服务CQRS架构。当前,我们在使用EF6时遇到了并发问题,我不知道如何进行分类。 首先,我有两个数据库(写和读)。我们正在使用SQL Server 2012作为RDBMS。我正在将IOC / DI与Autofac一起使用,并且由于我们有2个数据库,所以我想创建2个不同的上下文对象,这就是代码的样子。

//工作单元构造器

   public UnitOfWork(IContext readContext, IContext writeContext, IMapper 
    mapper)
    {
       _readContext = readContext;
      _writeContext = writeContext;
      _mapper = mapper; //this is for the automapper
    }

这将从IContext接口创建2个上下文对象。

// IContext接口具有以下两个自定义上下文对象

public partial class MyWriteContext : IContext,IDisposable
{
}

public partial class MyReadContext : IContext,IDisposable
{
}

我们已经故意创建了这两个类,因为这两个名称与我们用来创建实际Ef6 dbcontext的名称相同

//由反向poco生成的实际实体框架上下文对象

public partial class EfWriteContext : DbContext{}

partial class EFReadContext : DbContext{}

这是我的Autofac配置,用于相同的dbcontext,工作单元和通用存储库,这些配置都在autofac模块中定义并在Web API Startup.cs中注册和解析

//上下文自动注册模块

protected override void Load(ContainerBuilder builder)
        {
            builder.RegisterType<MyReadContext>()
                .Named<IContext>("MyReadContext")
                .InstancePerDependency();

            builder.RegisterType<MyWriteContext>()
                   .Named<IContext>("MyWriteContext")
                   .InstancePerDependency();
        }

        protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration)
        {
            registration.Preparing -= Registration_Preparing;
            registration.Preparing += Registration_Preparing;
        }

        private void Registration_Preparing(object sender, PreparingEventArgs e)
        {
            Parameter parameter = new ResolvedParameter(
                (pi, c) => pi.ParameterType == typeof(IContext),
                                        (pi, c) =>
                                        {
                                            if (pi.Name.Equals("readContext", StringComparison.OrdinalIgnoreCase))
                                            {
                                                return c.ResolveNamed<IContext>("MyReadContext");
                                            }
                                            else if (pi.Name.Equals("writeContext", StringComparison.OrdinalIgnoreCase))
                                            {
                                                return c.ResolveNamed<IContext>("MyWriteContext");
                                            }
                                            else
                                            {
                                                return c.ResolveNamed<IContext>("MyReadContext");
                                            }
                                        });
            e.Parameters = e.Parameters.Concat(new Parameter[] { parameter });
        }

//工作单元

 builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerDependency();

//存储库

builder.RegisterAssemblyTypes(Assembly.Load("Infrastructure"))
                          .Where(t => t.Name.EndsWith("Repository"))
                          .AsImplementedInterfaces()
                          .InstancePerDependency();

//存储库构造器

public Repository(IContext dbContext)
 {
    context = dbContext;
    _dbset = context.Set<TEntity>();
 }

在调用writecontext.SaveChanges()的情况下,此代码可以完美地工作并在单个用户的情况下插入和更新数据。如果在数据库中保存数据时多个用户之间有时间间隔,它甚至可以工作,但是当2个用户实际上试图同时在数据库中保存数据时,就会出现问题。然后开始抛出错误

  1. 参数'entitySetName'不能为null,为空或仅包含空格。

  2. 模型中已经存在项目。

  3. 违反PRIMARY KEY约束。无法在对象中插入重复的密钥。重复的键值为(0,4862)。该声明已终止。

,随后所有用户的调用也开始失败。

0 个答案:

没有答案