Base solution for your next web application
Open Closed

How can multiple DbContexts work together same application? #2598


User avatar
0
bilalhaidar created

Hi, I was checking this github: <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate-samples/tree/master/MultipleDbContextDemo">https://github.com/aspnetboilerplate/as ... ontextDemo</a>

I am wondering, how would IRepository<Person> make use of "Default" DbContext, while IRepository<Course> make use of "Second" DbContext?

How do you direct each IRepository to use a different DbContext?

Thanks


6 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    We register them for each dbContext seperately. You can see it here <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate/blob/master/src/Abp.EntityFramework/EntityFramework/AbpEntityFrameworkModule.cs#L53">https://github.com/aspnetboilerplate/as ... ule.cs#L53</a>

  • User Avatar
    0
    bilalhaidar created

    Great.

    Assuming I have 2 business modules.

    Module 1: Contains entities like Car, Driver, etc. (all detailed properties) Module 2: Requires an entity Car but not all of the properties maybe only Id, Name.

    I could create 2 DB Contexts, one in each project. Also, I will have entity Car defined in 2 places, in the first module with all properties and in the second module with only Id and Name.

    Module 1 will be responsible for creating the tables in DB in this case.

    So, in this case, I have 2 BaseRepositories each targeting a different DbContext. However, same entity like Car will appear in 2 DbContext.

    Going back to the source code you referred me to,:

    var primaryKeyType = EntityHelper.GetPrimaryKeyType(entityTypeInfo.EntityType);
                    if (primaryKeyType == typeof(int))
                    {
                        var genericRepositoryType = autoRepositoryAttr.RepositoryInterface.MakeGenericType(entityTypeInfo.EntityType);
                        if (!iocManager.IsRegistered(genericRepositoryType))
                        {
                            var implType = autoRepositoryAttr.RepositoryImplementation.GetGenericArguments().Length == 1
                                    ? autoRepositoryAttr.RepositoryImplementation.MakeGenericType(entityTypeInfo.EntityType)
                                    : autoRepositoryAttr.RepositoryImplementation.MakeGenericType(entityTypeInfo.DeclaringType, entityTypeInfo.EntityType);
    
                            iocManager.Register(
                                genericRepositoryType,
                                implType,
                                DependencyLifeStyle.Transient
                                );
                        }
                    }
    

    This means that IRepository<Car> would map to EfRepository<Module1DbContext, Car, int>. So Module1RepositoryBase will be created based on EfRepository<Module1DbContext, Car, int>.

    Now, in Module 2, given the code referenced above, we will have something similar: IRepository<Car> would map to EfRepository<Module3DbContext, Car, int>. So Module3RepositoryBase will be created based on EfRepository<Module2DbContext, Car, int>.

    Now, in the code, how would it know which DbContext to use?

    Thanks

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    In this case you can create two different Car entitys for each module and map them to same database table. Otherwise it is not possible to find right DbContext in this case.

  • User Avatar
    0
    bilalhaidar created

    Excellent! That's what I was hoping it will work.

    Then, I will use one of the DbContexts only to update database, not both will do that.

    Shall I set "SetInitializer(null)" in the Module class, inside the module that I want it to just "READ" from the db and ot change any table structure? Or no need?

    Regards Bilal

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    I think there is no need for that but I couldn't be sure, it is better to try and see :)

  • User Avatar
    0
    bilalhaidar created

    Thanks :) As long as I don't hit Update-Database should be fine :)