Base solution for your next web application
Open Closed

How to add Multiple dbcontext for multiple databases #170


User avatar
0
nidhisharma created

How to add another dbcontext in the the application? The steps I followed:

  1. I have added a new connectionstring in the config file with name='con2'.

  2. Created dbcontext similar to existing one inheriting AbpDbContext and passed connection string name here in constructor public Con2Context() : base("con2") {

     }
    
  3. But Preinitialize() method calls only con1. Configuration.DefaultNameOrConnectionString = "con1";

where do I configure con2 connnection? Right now, it is ignoring con2 and using con1 only for Con2Context. Please help!


16 Answer(s)
  • User Avatar
    0
    hikalkan created
    Support Team

    Hi,

    Since this topic is asked by also other people, I decided to prepare a simple running application. Download it from here: <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate-samples/tree/master/Others">https://github.com/aspnetboilerplate/as ... ter/Others</a>

    I created 2 different DbContext and 2 different migrations in same project. See migration command reference: <a class="postlink" href="http://coding.abel.nu/2012/03/ef-migrations-command-reference/">http://coding.abel.nu/2012/03/ef-migrat ... reference/</a>

    I added a new connection string named 'Second':

    <add name="Default" connectionString="Server=localhost; Database=MultipleDbContextDemo; Trusted_Connection=True;" providerName="System.Data.SqlClient" />
        <add name="Second" connectionString="Server=localhost; Database=MultipleDbContextDemoSecondDb; Trusted_Connection=True;" providerName="System.Data.SqlClient" />
    

    Then Added second db context:

    public class MySecondDbContext : AbpDbContext
        {
            public virtual IDbSet<Course> Courses { get; set; }
    
            public MySecondDbContext()
                : base("Second")
            {
                
            }
        }
    

    Then enabled migrations:

    Enable-Migrations -MigrationsDirectory "MigrationsSecond" -ContextTypeName "MySecondDbContext"
    

    When using add-migration and update database, we use configuration type name, like:

    Update-Database -ConfigurationTypeName "MultipleDbContextDemo.MigrationsSecond.Configuration"
    

    An application services both dbcontext (over 2 repositories):

    public class TestAppService : MultipleDbContextDemoAppServiceBase, ITestAppService
        {
            private readonly IRepository<Person> _persons;
            private readonly IRepository<Course> _courseRepository;
    
            public TestAppService(IRepository<Person> persons, IRepository<Course> courseRepository)
            {
                _persons = persons;
                _courseRepository = courseRepository;
            }
    
            public List<string> GetFromFirstDb()
            {
                var peopleNames = _persons.GetAllList().Select(p => p.PersonName).ToList();
                return peopleNames;
            }
    
            public List<string> GetFromSecondDb()
            {
                var courseNames =  _courseRepository.GetAllList().Select(p => p.CourseName).ToList();
                return courseNames;
            }
    
            public List<string> GetFromBothDbs()
            {
                List<string> names = new List<string>();
    
                var peopleNames = _persons.GetAllList().Select(p => p.PersonName).ToList();
                names.AddRange(peopleNames);
    
                var courseNames = _courseRepository.GetAllList().Select(p => p.CourseName).ToList();
                names.AddRange(courseNames);
    
                return names;
            }
        }
    

    Note that: GetFromBothDbs() may not work. You should start Distributed Transaction Coordinator windows service..

    For details, see source codes. After downloading solution, first create 2 databases using following commands:

    Update-Database -ConfigurationTypeName "MultipleDbContextDemo.Migrations.Configuration"

    Update-Database -ConfigurationTypeName "MultipleDbContextDemo.MigrationsSecond.Configuration"

    I hope this help you.

  • User Avatar
    0
    nobruds created

    Wow, nice =)

    I will check this later. It works only for EF or does too for NH ?

    Thanks

  • User Avatar
    0
    tiandao created

    very very good~thanks hikalkan!

  • User Avatar
    0
    hikalkan created
    Support Team

    Hi,

    This is for EF, not NH.

  • User Avatar
    0
    nobruds created

    <cite>hikalkan: </cite> Hi,

    This is for EF, not NH.

    Ohhh, :| thats ok. I will try to make one to work with NH following your help on my topic.

    Thanks again.

  • User Avatar
    0
    nidhisharma created

    Thanks, It worked.

    The mistake was this code:

    /* NOTE: This constructor is used by ABP to pass connection string */ public Con2DbContext(string nameOrConnectionString) : base(nameOrConnectionString) { } When I removed this line after seeing your code...it worked.

    Thanks again.

  • User Avatar
    0
    nobruds created

    Hi, I am back trying to resolve my issue on this.

    I want to make some changes so I can use that on NHibernate. I just need to make the changes you did on EntityFrameworkGenericRepositoryRegistrar on the NhRepositoryInstaller ?

    thanks

  • User Avatar
    0
    hikalkan created
    Support Team

    Yes, while I haven't thought too much, it seems like that. The problem is: when you inject IRepository<Person> how can we know which session (database connection) will be used. I solved it for EF but not thought much for NH yet.

  • User Avatar
    0
    nobruds created

    Hello Hikalkan

    I am still trying to figure out how to do this, I found this article from Fabio Maulo but I can't figure how to implement this on your ABP framework. I am still very new to DI (using castle) and NHibernate.

    If its not too much to ask, can you have a look e share some ideas ? [http://fabiomaulo.blogspot.com.br/2009/09/configure-sessionfactory-providers.html])

    Thanks

  • User Avatar
    0
    hikalkan created
    Support Team

    Have you written any code? If so, you can share with us, so I can check it, maybe fix it.

  • User Avatar
    0
    nobruds created

    Yes, I did some but not according that last article.

    I made changes on AbpNHibernateModule.cs, AbpNHibernateConfigurationExtensions.cs and NhRepositoryInstaller.cs.

    I will adapt it and post here.

    thanks

    edit: the article [http://fabiomaulo.blogspot.com.br/2009/09/configure-sessionfactory-providers.html])

  • User Avatar
    0
    hussein created

    I followed your steps and everything is working great, but the only problem is how to create a repository class for an entity from the second dbContext.

    The repository class inherits from RepositroyBase<entity> and the constructor takes any class that inherts AbpDbContext class.

    what i need now is to use Context property on my repository and see its own IDbSet<Entity>.

  • User Avatar
    0
    hikalkan created
    Support Team

    Hi,

    There is a base repository class which accepts also a DbContext type. Example:

    public class MyEntityRepository : EfRepositoryBase<MyDbContext, MyEntity, int>, IMyEntityRepository
            {
                public MyModuleRepositoryBase(IDbContextProvider<MyDbContext> dbContextProvider)
                    : base(dbContextProvider)
                {
                }
            }
    
  • User Avatar
    0
    mhdbaz created

    <cite>hikalkan: </cite> Hi,

    Since this topic is asked by also other people, I decided to prepare a simple running application. Download it from here: <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate-samples/tree/master/Others">https://github.com/aspnetboilerplate/as ... ter/Others</a>

    I created 2 different DbContext and 2 different migrations in same project. See migration command reference: <a class="postlink" href="http://coding.abel.nu/2012/03/ef-migrations-command-reference/">http://coding.abel.nu/2012/03/ef-migrat ... reference/</a>

    I added a new connection string named 'Second':

    <add name="Default" connectionString="Server=localhost; Database=MultipleDbContextDemo; Trusted_Connection=True;" providerName="System.Data.SqlClient" />
       <add name="Second" connectionString="Server=localhost; Database=MultipleDbContextDemoSecondDb; Trusted_Connection=True;" providerName="System.Data.SqlClient" />
    

    Then Added second db context:

    public class MySecondDbContext : AbpDbContext
       {
           public virtual IDbSet<Course> Courses { get; set; }
    
           public MySecondDbContext()
               : base("Second")
           {
               
           }
       }
    

    Then enabled migrations:

    Enable-Migrations -MigrationsDirectory "MigrationsSecond" -ContextTypeName "MySecondDbContext"
    

    When using add-migration and update database, we use configuration type name, like:

    Update-Database -ConfigurationTypeName "MultipleDbContextDemo.MigrationsSecond.Configuration"
    

    An application services both dbcontext (over 2 repositories):

    public class TestAppService : MultipleDbContextDemoAppServiceBase, ITestAppService
       {
           private readonly IRepository<Person> _persons;
           private readonly IRepository<Course> _courseRepository;
    
           public TestAppService(IRepository<Person> persons, IRepository<Course> courseRepository)
           {
               _persons = persons;
               _courseRepository = courseRepository;
           }
    
           public List<string> GetFromFirstDb()
           {
               var peopleNames = _persons.GetAllList().Select(p => p.PersonName).ToList();
               return peopleNames;
           }
    
           public List<string> GetFromSecondDb()
           {
               var courseNames =  _courseRepository.GetAllList().Select(p => p.CourseName).ToList();
               return courseNames;
           }
    
           public List<string> GetFromBothDbs()
           {
               List<string> names = new List<string>();
    
               var peopleNames = _persons.GetAllList().Select(p => p.PersonName).ToList();
               names.AddRange(peopleNames);
    
               var courseNames = _courseRepository.GetAllList().Select(p => p.CourseName).ToList();
               names.AddRange(courseNames);
    
               return names;
           }
       }
    

    Note that: GetFromBothDbs() may not work. You should start Distributed Transaction Coordinator windows service..

    For details, see source codes. After downloading solution, first create 2 databases using following commands:

    Update-Database -ConfigurationTypeName "MultipleDbContextDemo.Migrations.Configuration"

    Update-Database -ConfigurationTypeName "MultipleDbContextDemo.MigrationsSecond.Configuration"

    I hope this help you.

    Hello Halil I was reading about unit of work and How aspnetboilerplate automatically start a transaction on calling any Application Service method here <a class="postlink" href="http://aspnetboilerplate.com/Pages/Documents/Unit-Of-Work">http://aspnetboilerplate.com/Pages/Docu ... it-Of-Work</a> Do you mean that Starting the MSDTC on the server will fix the issues regarding starting Two transaction ? Dose aspnetboilerplate unit of work deal with this scenarios where multi tenant application should use different database for each tenant ? Please help because I am new to aspnetboilerplate and I also should use Single Application/Multi Database approach.

    My scenario is Single Deployment - Multiple Database in the below link I just want to make sure that aspnetboilerplate work with Single Deployment - Multiple Database or How I should implement my Application Service classes in order to get aspnetboilerplate works with Single Deployment - Multiple Database <a class="postlink" href="http://aspnetboilerplate.com/Pages/Documents/Multi-Tenancy">http://aspnetboilerplate.com/Pages/Docu ... ti-Tenancy</a>

    Thank you

  • User Avatar
    0
    papinaser created

    <cite>mhdbaz: </cite>

    <cite>hikalkan: </cite> Hi,

    Since this topic is asked by also other people, I decided to prepare a simple running application. Download it from here: <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate-samples/tree/master/Others">https://github.com/aspnetboilerplate/as ... ter/Others</a>

    I created 2 different DbContext and 2 different migrations in same project. See migration command reference: <a class="postlink" href="http://coding.abel.nu/2012/03/ef-migrations-command-reference/">http://coding.abel.nu/2012/03/ef-migrat ... reference/</a>

    I added a new connection string named 'Second':

    <add name="Default" connectionString="Server=localhost; Database=MultipleDbContextDemo; Trusted_Connection=True;" providerName="System.Data.SqlClient" />
       <add name="Second" connectionString="Server=localhost; Database=MultipleDbContextDemoSecondDb; Trusted_Connection=True;" providerName="System.Data.SqlClient" />
    

    Then Added second db context:

    public class MySecondDbContext : AbpDbContext
       {
           public virtual IDbSet<Course> Courses { get; set; }
    
           public MySecondDbContext()
               : base("Second")
           {
               
           }
       }
    

    Then enabled migrations:

    Enable-Migrations -MigrationsDirectory "MigrationsSecond" -ContextTypeName "MySecondDbContext"
    

    When using add-migration and update database, we use configuration type name, like:

    Update-Database -ConfigurationTypeName "MultipleDbContextDemo.MigrationsSecond.Configuration"
    

    An application services both dbcontext (over 2 repositories):

    public class TestAppService : MultipleDbContextDemoAppServiceBase, ITestAppService
       {
           private readonly IRepository<Person> _persons;
           private readonly IRepository<Course> _courseRepository;
    
           public TestAppService(IRepository<Person> persons, IRepository<Course> courseRepository)
           {
               _persons = persons;
               _courseRepository = courseRepository;
           }
    
           public List<string> GetFromFirstDb()
           {
               var peopleNames = _persons.GetAllList().Select(p => p.PersonName).ToList();
               return peopleNames;
           }
    
           public List<string> GetFromSecondDb()
           {
               var courseNames =  _courseRepository.GetAllList().Select(p => p.CourseName).ToList();
               return courseNames;
           }
    
           public List<string> GetFromBothDbs()
           {
               List<string> names = new List<string>();
    
               var peopleNames = _persons.GetAllList().Select(p => p.PersonName).ToList();
               names.AddRange(peopleNames);
    
               var courseNames = _courseRepository.GetAllList().Select(p => p.CourseName).ToList();
               names.AddRange(courseNames);
    
               return names;
           }
       }
    

    Note that: GetFromBothDbs() may not work. You should start Distributed Transaction Coordinator windows service..

    For details, see source codes. After downloading solution, first create 2 databases using following commands:

    Update-Database -ConfigurationTypeName "MultipleDbContextDemo.Migrations.Configuration"

    Update-Database -ConfigurationTypeName "MultipleDbContextDemo.MigrationsSecond.Configuration"

    I hope this help you.

    Hello Halil I was reading about unit of work and How aspnetboilerplate automatically start a transaction on calling any Application Service method here <a class="postlink" href="http://aspnetboilerplate.com/Pages/Documents/Unit-Of-Work">http://aspnetboilerplate.com/Pages/Docu ... it-Of-Work</a> Do you mean that Starting the MSDTC on the server will fix the issues regarding starting Two transaction ? Dose aspnetboilerplate unit of work deal with this scenarios where multi tenant application should use different database for each tenant ? Please help because I am new to aspnetboilerplate and I also should use Single Application/Multi Database approach.

    My scenario is Single Deployment - Multiple Database in the below link I just want to make sure that aspnetboilerplate work with Single Deployment - Multiple Database or How I should implement my Application Service classes in order to get aspnetboilerplate works with Single Deployment - Multiple Database <a class="postlink" href="http://aspnetboilerplate.com/Pages/Documents/Multi-Tenancy">http://aspnetboilerplate.com/Pages/Docu ... ti-Tenancy</a>

    Thank you

    I have same problem too.please help me about how to have single development with multi database? (Each database is for some features of my application)

    Thankyou

  • User Avatar
    0
    hikalkan created
    Support Team

    We are working for "single deployment multiple database", or "database per tenant" architecture (in this branch: <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate/tree/dev-db-per-tenant">https://github.com/aspnetboilerplate/as ... per-tenant</a>). It will be finished and published soon. Currently, ABP itself is not ready to this architecture.