【问题标题】:Working with multiple Db`s. How to inject DbContexts connected to different Dbs?与多个 Db 一起工作。如何注入连接到不同 Dbs 的 DbContexts?
【发布时间】:2015-01-26 03:51:59
【问题描述】:

使用以下两个链接,我已经使用 Repo、工作单元、EF、DI 实现了我的项目。

  1. http://www.codeproject.com/Articles/814768/CRUD-Operations-Using-the-Generic-Repository-Patte
  2. http://www.codeproject.com/Articles/838097/CRUD-Operations-Using-the-Generic-Repository-Pat

但过了一段时间,由于遗留数据库,我不得不为两个数据库扩展我的项目。 但到目前为止,我无法扩展我的项目以便可以使用两个数据库。 任何人都可以根据提到的链接向我提供有关使用多个数据库的任何解决方案吗?

提前谢谢你。

更新

核心

   **Financial Database**

public class Vou : Entity
  {
     public Nullable<long> Num { get; set; }
     public string Subj { get; set; }
  }

   **Trading Database**

public class Goods : Entity
  {
    public long Code { get; set; }
    public string Title { get; set; }
  }

数据

public interface IDbContext
    {
        IDbSet<TEntity> Set<TEntity>() where TEntity : Entity;
        int SaveChanges();
    }


public class IocDbContext : DbContext, IDbContext
    {
        public IocDbContext()
            : base("name=FinancialEntities")
        {
        }

        public new IDbSet<TEntity> Set<TEntity>() where TEntity : Entity
        {
            return base.Set<TEntity>();
        }
    }


 public interface IRepository< TEntity>
    {
        TEntity Get(int id);
    }



public class Repository<T> : IRepository<T> where T : Entity 
    {
        protected readonly DbContext context;
        private IDbSet<T> _entities;

        public Repository(IocDbContext context)
        {
            this.context = context;
        }

        public void Save()
        {
            this.context.SaveChanges();
        }
}

【问题讨论】:

    标签: entity-framework asp.net-mvc-4 dependency-injection repository-pattern structuremap


    【解决方案1】:

    多个数据库意味着每个 dbContext 的连接。在这两篇文章中,DbContext 都是这样创建的:

       public EFDbContext()
           : base("name=DbConnectionString")
       {
       }
    

    然后在 Repos ctor 中:

        public Repository(EFDbContext context)
        {
            this.context = context;
        }
    

    您需要的是 EFDbContext 中的另一个 ctor,如下所示:

        public EFDbContext (DbConnection connection)
            : base(connection, true)
        {
    
        }
    

    并像这样在回购中传递它:

        public Repository(IDbContextProvider contextProvider)
        {
            this._contextProvider = contextProvider;
        }
    

    你需要像这样的 IDbContextProvider :

        public interface IDbContextProvider
        {
            DbContext Current(); // implicitly provided (from current HttpContext)
            DbContext Specific(string dbName); // the caller provides it
        }
    

    在 IDbContextProvider 的实现中,您可以放置​​您需要的逻辑来创建您的特定数据库连接。我对多个数据库使用这样的实现,效果很好。

    根据经验:“当您需要另一个级别的间接时,您将需要另一个级别的抽象。”

    在您的情况下,您需要另一个级别的间接,而不仅仅是单个数据库上下文,而是多个。所以路径在连接级别上相乘:

    • user1-db1
    • user1-db2
    • userN-dbM
    • ....

    因此,肉进入 IDbContextProvider.Current()。

    怎么样?例如,您可以调用 IDbContextProvider.Current() 并通过一些 url-to-db 映射获取 dbName。另一种方法 - 从 cookie 中获取用户 ID 并进行用户 ID 到数据库的映射。取决于你的具体情况。

    更新 这是温莎城堡的一个例子:

     private static DbContextAdapter DbContextAdapterFactoryMethod(IKernel k, ComponentModel cm, CreationContext c)
        {
            IEfLogger logger = k.Resolve<IEfLogger>();
            if (c.HasAdditionalArguments)
            {
                IDbModel model = (IDbModel)c.AdditionalArguments["model"];
                IDbConnection connection = (IDbConnection)c.AdditionalArguments["connection"];
                return DbContextAdapter.CreateCompanyContext(model, connection, logger);
            }
            else
            {
                return DbContextAdapter.CreateMainContext(logger);
            }
        }
    

    在上面的示例中,DbContext 的创建是由参数驱动的。没有默认构造函数。

    【讨论】:

    • 感谢您的时间和考虑,但老实说,我无法理解您的观点。另外,如果您的意思是,我将上下文传递给存储库,如果不同数据库的两个表之间存在任何连接,我该怎么办。能否请您为我澄清更多?
    • 非常感谢您的帮助。但实际上我更加困惑。我已经用我的代码更新了我的问题。您能否根据您的建议更正我的代码,以便同时使用“交易数据库”?
    • 您在服务中使用旅游存储库吗?
    • 谢谢。是的,我使用 IoC 的结构图。我的方式与我在问题中提到的链接非常相​​似。 codeproject.com/Articles/838097/... 在此先感谢您的帮助
    • 文章中的实现与手头的需求不匹配。我的意思是,在文章中 DbContext 有一个定义了连接字符串的 ctor,但要求是针对具有两个不同连接字符串的两个不同上下文。解决方案是通过引入 DbContextFactory 将 DbContexts 的实例化出存储库,它为存储库提供 IDbContext 而不是具体的 DbContext 本身。然后在工厂中,您可以进行识别步骤 - “我应该将哪个具体的 DbContext 推送到 Repository?”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-29
    • 2019-03-08
    • 1970-01-01
    • 2011-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多