Base solution for your next web application
Open Closed

Separate Databases and DBContext - #7314


User avatar
0
OutdoorEd created

I am working with ABP 7.0.0 Asp Net Core 2.2 & Jquery using NetZero as the Authentication layer to access several different databases that, for business purposes, must be kept separate from the ABP Database. Each of my other databases has all of the required ABP Fields to be fully IMustHaveTenant compatible. Once logged in TenantId, User, Role is in Session and should be able to be passed to the other databases.

I've looked at various forum posts and Github code for having multiple databases and more than one DbContext pointing to different connection strings but I haven't been able to get those approached to work in Net Core 2.2. Has anyone gotten this scenario to work in Net Core 2.2? I would appreciate seeing


4 Answer(s)
  • User Avatar
    0
    alper created
    Support Team

    Does this work for you?

  • User Avatar
    0
    OutdoorEd created

    In my case there are three separate databases (Applications, Programs, Trips) that I will need to connect to from the same Tenant. The built-in structure seems like it stores 1 additional connection string somewhere in an Abp-Table in the database. Does this method allow for more than 1 additional connection string per Tenant? Also, does this use a separate DbContext for the additional databases or is there 1 DbContext for everything? I would prefer to use separate DbContexts.

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @outdoored

    Have you seen this https://github.com/aspnetboilerplate/aspnetboilerplate-samples/tree/master/MultipleDbContextEfCoreDemo ?

    Currently, Tenant entity only stores one connection string. However, you can extend the Tenant entity to add different connection strings (https://docs.aspnetzero.com/documents/aspnet-core-mvc/latest/Extending-Existing-Entities) and then you can implement a custom connenction string resolver similar to https://github.com/aspnetboilerplate/aspnetboilerplate/blob/dev/src/Abp.Zero.EntityFramework/Zero/EntityFramework/DbPerTenantConnectionStringResolver.cs

  • User Avatar
    0
    OutdoorEd created

    Thanks, I looked at the MultipleDbContextEfCoreDemo but it isn't a full implementation of 7.0 (or maybe it is based a 6.x version) since there are classes in 7.0 (ex. EntityFrameworkCore\PredicateBuilder.cs and the EntityFrameworkCore\Repositories\TENENTNAME_RepositoryBase.cs classes which don't exist in the MultipleDbContextEfCoreDemo solution, so it isn't clear how to fully implement the MultipleDbContextEfCoreDemo approach in 7.0 and have the Repositories in the different DbContexts work.

    It really would be helpful to see a full implementation ABP Implementation of this rather than a prooof of concept that touches two dummy classes and does not have all the necessary code to do this in Net Core 2.2

    I've implemented all the classes from MultipleDbContextEfCoreDemo and run the application and the NetZero login pages work showing that it is connecting to the NetZero Database through the DbConnectionOptionsConfigurer but when I try and open the Index Razor page calling into my Second Database I get

    HandlerException: Can't create component 'TENANTNAME.EntityFrameworkCore.SECONDDbContext' as it has dependencies to be satisfied. 'TENANTNAME.EntityFrameworkCore.SECONDDbContext' is waiting for the following dependencies: - Service 'Microsoft.EntityFrameworkCore.DbContextOptions`1[[TENANTNAME.EntityFrameworkCore.SECONDDbContext, OA_Tenant.EntityFrameworkCore, Version=6.5.0.0, Culture=neutral, PublicKeyToken=null]]' which was not registered.

    Here is my Razor Page code which obviously isn't seeing the SECONDDbContext

    using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.EntityFrameworkCore; using OA_Tenant.Applications.Entity; using OA_Tenant.EntityFrameworkCore; using Kendo.Mvc.Extensions; using Kendo.Mvc.UI;

    namespace OA_Tenant.Web.Mvc.Areas.Applications.Pages.Interviews { public class IndexModel : PageModel { private readonly OA_Tenant.EntityFrameworkCore.SECONDDbContext _context;

        public IndexModel(OA_Tenant.EntityFrameworkCore.SECONDDbContext context)
        {
            _context = context;
        }
    
        public IList<OA_Tenant.Applications.Entity.Interviews> Interviews { get;set; } 
    
        public async Task OnGetAsync()
        {
            Interviews = await _context.Interviews.ToListAsync();
        }
    

    In the MultipleDbContextEfCoreDemo the only DbContext registered in Startup is DbContextOptionsConfigurer.Configure(options.DbContextOptions, options.ConnectionString);

    In my Startup I have

            services.AddAbpDbContext<FIRSTDbContext>(options =>
           {
               FIRSTDbContextOptionsConfigurer.Configure(options.DbContextOptions, options.ConnectionString);
           });
       
       I tried registering the Second DbContext but that also fails
       
         services.AddAbpDbContext<SECONDDbContext>(options =>
             {
                 ApplicationsDbContextOptionsConfigurer.Configure(options.DbContextOptions, options.ConnectionString);
             });
    

    Also, I am not sure how to be able to use all my SecondDbContext Repositories since the RepositoryBase class references the FIRST/ORIGINAL DbContext.

    public abstract class TENANTNAMERepositoryBase<TEntity, TPrimaryKey> : EfCoreRepositoryBase<TENANTNAMEDbContext, TEntity, TPrimaryKey> where TEntity : class, IEntity

        protected OA_TenantRepositoryBase(IDbContextProvider<TENANTNAMEDbContext> dbContextProvider)
            : base(dbContextProvider)
        {
    
        }