Good day, ANZ admins,
We're using AspNetZero version 10.2.0 (2021-01-29). We're also using EntityFramework Code-First Migration.
We want to use some of the ANZ functionalities, but some functionalities we won't use. We also want to use two databases. One for the Business Logic Database and one for the Web Interface Database. We've already configured ANZ to use two databases by creating a second db context. The existing first db context is for the Business Logic Database. The second db context that we've created is for the Web Interface Database. There are 42 existing ANZ tables, but we only need 19 of them. We know that we can't delete 23 other tables because behind the scene they're all being used, and we may also use them in the future. So instead of deleting them, we want those 23 tables to be placed in the Web Interface Database. That's our requirement. I only managed to put 3 tables (app_binary_object, app_chat_message, app_friendship) that we don't need in the Web Interface Database because their entities are present in the FirstDbContext.cs. For the other 20 tables, I can't find their definition. I also saw their entities are inside the DLL package.
Here's the list of 19 ANZ tables that we need and are now placed in the Business Logic Database:
- abp_audit_log
- abp_edition
- abp_feature
- abp_language
- abp_language_text
- abp_setting
- abp_tenant
- abp_tenant_notification
- abp_user
- abp_user_account
- abp_user_claim
- abp_user_login
- abp_user_login_attempt
- abp_user_notification
- abp_user_token
- app_invoice
- app_subscription_payment
- app_subscription_payments_extension_datum
- app_user_delegation
Here's the list of 20 ANZ tables that we don't need and are currently in the Business Logic Database and want to be placed in the Web Interface Database:
- abp_dynamic_entity_property
- abp_dynamic_entity_property_value
- abp_dynamic_property
- abp_dynamic_property_value
- abp_entity_change
- abp_entity_change_set
- abp_entity_property_change
- abp_background_job
- abp_notification
- abp_notification_subscription
- abp_organization_unit
- abp_organization_unit_role
- abp_permission
- abp_role
- abp_role_claim
- abp_user_organization_unit
- abp_user_role
- abp_webhook_event
- abp_webhook_send_attempt
- abp_webhook_subscription
Here are the 3 ANZ tables that I managed to put in the Web Interface Database:
- app_binary_object
- app_chat_message
- app_friendship
Please help us with this requirement. Thank you in advance.
3 Answer(s)
-
0
Hi,
I'm not sure if this scenario is fully supported or not but those tables are defined in https://github.com/aspnetboilerplate/aspnetboilerplate/blob/dev/src/Abp.ZeroCore.EntityFrameworkCore/Zero/EntityFrameworkCore/AbpZeroDbContext.cs and some of them are defined in https://github.com/aspnetboilerplate/aspnetboilerplate/blob/dev/src/Abp.ZeroCore.EntityFrameworkCore/Zero/EntityFrameworkCore/AbpZeroCommonDbContext.cs
So, you can try removing base class from your DbContext and manually add entities to your DbContext.
-
0
Hi,
I'm not sure if this scenario is fully supported or not but those tables are defined in https://github.com/aspnetboilerplate/aspnetboilerplate/blob/dev/src/Abp.ZeroCore.EntityFrameworkCore/Zero/EntityFrameworkCore/AbpZeroDbContext.cs and some of them are defined in https://github.com/aspnetboilerplate/aspnetboilerplate/blob/dev/src/Abp.ZeroCore.EntityFrameworkCore/Zero/EntityFrameworkCore/AbpZeroCommonDbContext.cs
So, you can try removing base class from your DbContext and manually add entities to your DbContext.
Hi ismcagdas,
Thank you for your immediate response. Your advice really helped. However, I can't use the below definition, it says 'TUser' could not be found. I know I should not use the 'TUser', but I'm not sure what to use instead. Same for the TRoles and TTenants
public virtual DbSet<TUser> Users { get; set; }
public virtual DbSet<TRole> Roles { get; set; }
public virtual DbSet<TTenant> Tenants { get; set; }
Please help us again. Thank you.
-
0
Hi @dschnitt,
While I'm on an older version of ANZ and not running 10.2, I had looked into doing something like this a year ago for the AbpAuditLogs table, as well as another table that I have defined.
While I never ended up taking this to production, I built a proof-of-concept that used
AmbientDataContext
I had to do a couple of things:
- for the tables that I wanted to move, I had to create concrete repository classes for
- I had to define my own ConnectionStringResolver
Here is my concrete repository class
using Abp.Auditing; using Abp.EntityFrameworkCore; using Abp.Runtime; using Abp.Domain.Repositories; using Microsoft.Extensions.Logging; using Brian.EntityFrameworkCore.Repositories; using Brian.EntityFrameworkCore; namespace Brian.MultiTenancy.Auditing { public class AbpAuditLogsRepository : BrianRepositoryBase<AuditLog, long>, IRepository<AuditLog, long> { private readonly ILogger<AbpAuditLogsRepository> _logger; public AbpAuditLogsRepository(IDbContextProvider<BrianDbContext> dbContextProvider, IAmbientDataContext ambientDataContext, ILogger<AbpAuditLogsRepository> logger) : base(dbContextProvider) { _logger = logger; _logger.LogDebug("[AbpAuditLogsRepository] : setting AmbientDataContext 'DBCONTEXT' to 'AuditLog'"); ambientDataContext.SetData("DBCONTEXT", "AuditLog"); } } }
here is my ConnectionStringResolver
using System; using Abp.Configuration.Startup; using Abp.Domain.Uow; using Microsoft.Extensions.Configuration; using Brian.Configuration; using Abp.Reflection.Extensions; using Abp.Zero.EntityFrameworkCore; using Abp.MultiTenancy; using Abp.Runtime; using Microsoft.Extensions.Logging; namespace Brian.EntityFrameworkCore { public class BrianDbConnectionStringResolver : DbPerTenantConnectionStringResolver { private readonly IConfigurationRoot _appConfiguration; private readonly ILogger<BrianDbConnectionStringResolver> _logger; private readonly IAmbientDataContext _ambientDataContext; public BrianDbConnectionStringResolver(IAbpStartupConfiguration configuration, ICurrentUnitOfWorkProvider currentUnitOfWorkProvider, ITenantCache tenantCache, IAppConfigurationAccessor configurationAccessor, IAmbientDataContext ambientDataContext, ILogger<BrianDbConnectionStringResolver> logger) : base(configuration, currentUnitOfWorkProvider, tenantCache) { _ambientDataContext = ambientDataContext; _appConfiguration = configurationAccessor.Configuration; _logger = logger; } public override string GetNameOrConnectionString(ConnectionStringResolveArgs args) { var s = base.GetNameOrConnectionString(args); object dbContext = null; try { dbContext = _ambientDataContext.GetData("DBCONTEXT"); if(dbContext != null && dbContext.GetType().Equals(typeof(string))) { var context = (string)dbContext; _logger.LogDebug($"[BrianDbConnectionStringResolver.GetNameOrConnectionString] : Found 'DBCONTEXT' of '{context}'"); //how do we ensure that there _is_ a connectionString defined for the given Context var connectionString = _appConfiguration.GetConnectionString(context); if(!string.IsNullOrEmpty(connectionString)) { _logger.LogDebug($"[BrianDbConnectionStringResolver.GetNameOrConnectionString] : Found connectionString defined for 'DBCONTEXT' of '{context}'"); s = connectionString; } } } catch (Exception ex) { //can we log this _logger.LogError(ex, "[BrianDbConnectionStringResolver.GetNameOrConnectionString] : An unexpected error has occurred."); } return s; } } }
Then in my WebCoreModule, in the PreInitialize method:
public override void PreInitialize() { Configuration.ReplaceService<IConnectionStringResolver, BrianDbConnectionStringResolver>(); Configuration.ReplaceService<IRepository<AuditLog, long>, AbpAuditLogsRepository>(); ...
Disclaimer: this code was written against a much older version of ABP & ANZ, and written in just a few hours as part of a rapid proof-of-concept just to see if this was even feasible. It's definitely not my cleanest work, and it was never code reviewed or tested for production readiness. Additionally, I never looked into how this would be handled in for data migrations within EntityFrameworkCore, so it's possible that doing this could cause issues running the .Migrator project or running your EF migrations either code-first or via SQL scripts.
I don't know if ABP / ANZ still supports or recommends using
DbPerTenantConnectionStringResolver
orIAmbientDataContext
.I hope this helps. Good luck! -Brian