Base solution for your next web application
Open Closed

Display Tenant's data on host dashboard (using separate databases for tenants) #11314


User avatar
0
amasanad created

Prerequisites

Please answer the following questions before submitting an issue. YOU MAY DELETE THE PREREQUISITES SECTION.

  • What is your product version? v11.3.0
  • What is your product type (Angular or MVC)? Angular
  • What is product framework type (.net framework or .net core)? .net core

Hello Dear,

we are developing new portal with multitenancy enabled each tenant would be on a separate database as business requirement our concern now that we can't find a way to display all realted tenant’s entities data from the host dashboard

For Example If we have an Entity "Client" that is available on Host and Tenants with ImayHaveTenant interface is there a way to display all client’s information with different tenants on the host dashboard ?

I’m aware that there is impersonate feature where I can login by tenant username and see the client’s data for that tenant, but we asking if we able to manage this or display all records from host screens ?


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

    Hi @amasanad

    For such cases, it is better to collect all data in Host database and generate dashboard from Host database. We are following a similar approach for filling AbpUserAccounts table. You can create a table on Host side and also create a class similar to https://github.com/aspnetboilerplate/aspnetboilerplate/blob/dev/src/Abp.Zero.Common/Authorization/Users/UserAccountSynchronizer.cs for syncronizing data to Host database. After all, you can generate your report from Host database.

  • User Avatar
    0
    amasanad created

    Hi

    i've try to do Synchronizer class for an entity when trying to add new enitty from tenant it goes through infinite loop of insertiaons, what is the issue ?

    and i've another question how to handel primary keys on tenant for this case tenatn A can add new plan and with PK id = 1 tenatn B can add new plan and with PK id = 1 as they are on diffrenet databases, shall i add refrence to the PK like UserId on UserAccount ?

    /// <summary>
        /// Synchronizes a user's information to user account.
        /// </summary>
        public class InsurancePlanSynchronizer :
            IEventHandler<EntityCreatedEventData<InsurancePlan>>,
            //IEventHandler<EntityDeletedEventData<InsurancePlan>>,
            //IEventHandler<EntityUpdatedEventData<InsurancePlan>>,
            ITransientDependency
        {
            private readonly IRepository<InsurancePlan, int> _planRepository;
            private readonly IUnitOfWorkManager _unitOfWorkManager;
    
            /// <summary>
            /// Constructor
            /// </summary>
            public InsurancePlanSynchronizer(
                IRepository<InsurancePlan, int> planRepo,
                IUnitOfWorkManager unitOfWorkManager)
            {
                _planRepository = planRepo;
                _unitOfWorkManager = unitOfWorkManager;
            }
    
            /// <summary>
            /// Handles creation event of user
            /// </summary>
            public virtual void HandleEvent(EntityCreatedEventData<InsurancePlan> eventData)
            {
                _unitOfWorkManager.WithUnitOfWork(() =>
                {
                    using (_unitOfWorkManager.Current.SetTenantId(null))
                    {
                            _planRepository.Insert(new InsurancePlan
                            {
                                TenantId = eventData.Entity.TenantId,
                                NameAr = eventData.Entity.NameAr,
                            });
                         
                    }
                });
            }
        }
    

    PlanAppService

            [AbpAuthorize(AppPermissions.Pages_InsurancePlans_Create)]
            protected virtual async Task Create(CreateOrEditInsurancePlanDto input)
            {
                var insurancePlan = ObjectMapper.Map<InsurancePlan>(input);
    
                if (AbpSession.TenantId != null)
                {
                    insurancePlan.TenantId = (int?)AbpSession.TenantId;
                }
    
                await _insurancePlanRepository.InsertAsync(insurancePlan);
                await CurrentUnitOfWork.SaveChangesAsync(); 
    
            }
    
  • User Avatar
    0
    musa.demir created

    Hi @amasanad

    It happens because you use same table to sync data. IEventHandler<EntityCreatedEventData<InsurancePlan>> will always be fired after you create InsurancePlan. It will not check if It is in the tenant db or host db. You may use another db table to sync data on host side (like we did in https://github.com/aspnetboilerplate/aspnetboilerplate/blob/79f4de19f89885c51f65a69d1d7798309a70918e/src/Abp.Zero.Common/Authorization/Users/UserAccountSynchronizer.cs#L20). Or add a new field to your data to check if it is synchronized data or not. If it is synchronized data. Don't do anything. And you will breake the loop.

  • User Avatar
    0
    fawad29 created

    Hi @amasanad

    It happens because you use same table to sync data. IEventHandler<EntityCreatedEventData<InsurancePlan>> will always be fired after you create InsurancePlan. It will not check if It is in the tenant db or host db. You may use another db table to sync data on host side (like we did in https://github.com/aspnetboilerplate/aspnetboilerplate/blob/79f4de19f89885c51f65a69d1d7798309a70918e/src/Abp.Zero.Common/Authorization/Users/UserAccountSynchronizer.cs#L20). Or add a new field to your data to check if it is synchronized data or not. If it is synchronized data. Don't do anything. And you will breake the loop.

    Hi,

    We have a similar requirements as well but not related to the Dashboard. We need to display data from a table that exists in all separate tenant databases to a new page in Host. Is it possible to get data for all tenants if I logged in as host without duplicating data into host database? It is a make or break requirement for us! I am using latest version of aspnet core and angular project.