Nope. This didn't work either. Same issue. Now the error says the below after additng theDbTablePrefix of 'CF'
Exception thrown: 'Npgsql.PostgresException' in Microsoft.EntityFrameworkCore.Relational.dll An exception of type 'Npgsql.PostgresException' occurred in Microsoft.EntityFrameworkCore.Relational.dll but was not handled in user code 42P01: relation "CFLanguageTexts" does not exist
Please reference my original screenshot in terms of the table names.
Here is the related log messages.
2021-11-17 08:34:38.671 -05:00 [INF] Request starting HTTP/1.1 GET https://localhost:44300/api/abp/multi-tenancy/tenants/by-id/3a00402b-022a-c209-bd72-28f9859e70b4?api-version=1.0 - -
2021-11-17 08:34:38.946 -05:00 [INF] Successfully validated the token.
2021-11-17 08:34:38.961 -05:00 [INF] Executing endpoint 'Pages.Abp.MultiTenancy.AbpTenantController.FindTenantByIdAsync (Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy)'
2021-11-17 08:34:38.963 -05:00 [INF] Route matched with {area = "abp", action = "FindTenantById", controller = "AbpTenant", page = ""}. Executing controller action with signature System.Threading.Tasks.Task1[Volo.Abp.AspNetCore.Mvc.MultiTenancy.FindTenantResultDto] FindTenantByIdAsync(System.Guid) on controller Pages.Abp.MultiTenancy.AbpTenantController (Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy). 2021-11-17 08:34:38.979 -05:00 [INF] Executing action method Pages.Abp.MultiTenancy.AbpTenantController.FindTenantByIdAsync (Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy) - Validation state: "Valid" 2021-11-17 08:34:38.991 -05:00 [INF] Executed action method Pages.Abp.MultiTenancy.AbpTenantController.FindTenantByIdAsync (Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy), returned result Microsoft.AspNetCore.Mvc.ObjectResult in 12.2466ms. 2021-11-17 08:34:38.993 -05:00 [INF] Executing ObjectResult, writing value of type 'Volo.Abp.AspNetCore.Mvc.MultiTenancy.FindTenantResultDto'. 2021-11-17 08:34:38.995 -05:00 [INF] Executed action Pages.Abp.MultiTenancy.AbpTenantController.FindTenantByIdAsync (Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy) in 31.9413ms 2021-11-17 08:34:38.995 -05:00 [INF] Executed endpoint 'Pages.Abp.MultiTenancy.AbpTenantController.FindTenantByIdAsync (Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy)' 2021-11-17 08:34:38.995 -05:00 [INF] Request finished HTTP/1.1 GET https://localhost:44300/api/abp/multi-tenancy/tenants/by-id/3a00402b-022a-c209-bd72-28f9859e70b4?api-version=1.0 - - - 200 - application/json;+charset=utf-8 324.9255ms 2021-11-17 08:34:39.030 -05:00 [INF] Request starting HTTP/1.1 GET https://localhost:44300/api/abp/application-configuration?api-version=1.0 - - 2021-11-17 08:34:39.031 -05:00 [INF] Successfully validated the token. 2021-11-17 08:34:39.035 -05:00 [INF] Executing endpoint 'Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.AbpApplicationConfigurationController.GetAsync (Volo.Abp.AspNetCore.Mvc)' 2021-11-17 08:34:39.035 -05:00 [INF] Route matched with {area = "abp", action = "Get", controller = "AbpApplicationConfiguration", page = ""}. Executing controller action with signature System.Threading.Tasks.Task
1[Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.ApplicationConfigurationDto] GetAsync() on controller Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.AbpApplicationConfigurationController (Volo.Abp.AspNetCore.Mvc).
2021-11-17 08:34:39.036 -05:00 [INF] Executing action method Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.AbpApplicationConfigurationController.GetAsync (Volo.Abp.AspNetCore.Mvc) - Validation state: "Valid"
2021-11-17 08:34:39.057 -05:00 [INF] Entity Framework Core 5.0.12 initialized 'FeatureManagementDbContext' using provider 'Npgsql.EntityFrameworkCore.PostgreSQL' with options: QuerySplittingBehavior=SplitQuery
2021-11-17 08:34:39.069 -05:00 [INF] Executed DbCommand (3ms) [Parameters=[@__providerName_0='?', @__providerKey_1='?'], CommandType='"Text"', CommandTimeout='30']
SELECT f."Id", f."Name", f."ProviderKey", f."ProviderName", f."Value"
FROM "FeatureValues" AS f
WHERE (f."ProviderName" = @__providerName_0) AND (f."ProviderKey" = @__providerKey_1)
2021-11-17 08:34:39.348 -05:00 [INF] Entity Framework Core 5.0.12 initialized 'LanguageManagementDbContext' using provider 'Npgsql.EntityFrameworkCore.PostgreSQL' with options: QuerySplittingBehavior=SplitQuery
2021-11-17 08:34:39.427 -05:00 [ERR] Failed executing DbCommand (12ms) [Parameters=[@__ef_filter__p_0='?' (DbType = Boolean), @__ef_filter__CurrentTenantId_1='?' (DbType = Guid), @__resourceName_0='?', @__cultureName_1='?'], CommandType='"Text"', CommandTimeout='30']
SELECT l."Id", l."CreationTime", l."CreatorId", l."CultureName", l."LastModificationTime", l."LastModifierId", l."Name", l."ResourceName", l."TenantId", l."Value"
FROM "LanguageTexts" AS l
WHERE (@__ef_filter__p_0 OR (l."TenantId" = @__ef_filter__CurrentTenantId_1)) AND ((l."ResourceName" = @__resourceName_0) AND (l."CultureName" = @__cultureName_1))
2021-11-17 08:34:39.458 -05:00 [ERR] An exception occurred while iterating over the results of a query for context type 'Volo.Abp.LanguageManagement.EntityFrameworkCore.LanguageManagementDbContext'.
Npgsql.PostgresException (0x80004005): 42P01: relation "LanguageTexts" does not exist
at Npgsql.NpgsqlConnector.<ReadMessage>g__ReadMessageLong|194_0(NpgsqlConnector connector, Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications, Boolean isReadingPrependedMessage)
at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
at Npgsql.NpgsqlDataReader.NextResult()
at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior)
at Npgsql.NpgsqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader()
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
at Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable1.Enumerator.InitializeReader(DbContext _, Boolean result) at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.Execute[TState,TResult](TState state, Func
3 operation, Func3 verifySucceeded) at Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable
1.Enumerator.MoveNext()
Exception data:
Severity: ERROR
SqlState: 42P01
MessageText: relation "LanguageTexts" does not exist
Position: 170
File: d:\pginstaller_13.auto\postgres.windows-x64\src\backend\parser\parse_relation.c
Line: 1376
Routine: parserOpenTable
Npgsql.PostgresException (0x80004005): 42P01: relation "LanguageTexts" does not exist
at Npgsql.NpgsqlConnector.<ReadMessage>g__ReadMessageLong|194_0(NpgsqlConnector connector, Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications, Boolean isReadingPrependedMessage)
at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
at Npgsql.NpgsqlDataReader.NextResult()
at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken)
at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior)
at Npgsql.NpgsqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader()
at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
at Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable1.Enumerator.InitializeReader(DbContext _, Boolean result) at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.Execute[TState,TResult](TState state, Func
3 operation, Func3 verifySucceeded) at Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable
1.Enumerator.MoveNext()
at System.Collections.Generic.List1..ctor(IEnumerable
1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Volo.Abp.LanguageManagement.EntityFrameworkCore.EfCoreLanguageTextRepository.GetList(String resourceName, String cultureName) in C:\Src\StructureWeb\ABP-Pro-Modules\language-management\src\Volo.Abp.LanguageManagement.EntityFrameworkCore\Volo\Abp\LanguageManagement\EntityFrameworkCore\EfCoreLanguageTextRepository.cs:line 27
at Castle.Proxies.Invocations.ILanguageTextRepository_GetList.InvokeMethodOnTarget()
at Castle.DynamicProxy.AbstractInvocation.Proceed()
at Castle.DynamicProxy.AbstractInvocation.ProceedInfo.Invoke()
at Castle.DynamicProxy.AsyncInterceptorBase.ProceedSynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
Exception data:
Severity: ERROR
SqlState: 42P01
MessageText: relation "LanguageTexts" does not exist
Position: 170
File: d:\pginstaller_13.auto\postgres.windows-x64\src\backend\parser\parse_relation.c
Line: 1376
Routine: parserOpenTable
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(IConnectionStringResolver))]
public class SWMultiTenantConnectionStringResolver : MultiTenantConnectionStringResolver
{
private readonly ICurrentTenant _currentTenant;
private readonly IServiceProvider _serviceProvider;
public SWMultiTenantConnectionStringResolver(
IOptionsSnapshot<AbpDbConnectionOptions> options,
ICurrentTenant currentTenant,
IServiceProvider serviceProvider) : base(options, currentTenant, serviceProvider)
{
_currentTenant = currentTenant;
_serviceProvider = serviceProvider;
}
public override async Task<string> ResolveAsync(string connectionStringName = null)
{
string connectionstring = "";
//No current tenant, fallback to default logic
if (_currentTenant.Id == null)
{
return await base.ResolveAsync(connectionStringName);
}
if (_currentTenant.IsAvailable)
{
switch (connectionStringName)
{
case LanguageManagementDbProperties.ConnectionStringName:
case AbpPermissionManagementDbProperties.ConnectionStringName:
case FeatureManagementDbProperties.ConnectionStringName:
using (_currentTenant.Change(null))
{
connectionstring = await base.ResolveAsync(connectionStringName);
}
break;
case "Volo.Abp.Identity.EntityFrameworkCore.IIdentityProDbContext":
using (_currentTenant.Change(null))
{
connectionstring = await base.ResolveAsync(connectionStringName);
}
break;
case "Default":
using (_currentTenant.Change(null))
{
connectionstring = await base.ResolveAsync(connectionStringName);
}
break;
default:
var tenant = await FindTenantConfigurationAsync(_currentTenant.Id.Value);
if (tenant == null || tenant.ConnectionStrings.IsNullOrEmpty())
{
//Tenant has not defined any connection string, fallback to default logic
return await base.ResolveAsync(connectionStringName);
}
connectionstring = tenant.ConnectionStrings.Default;
break;
}
}
//Replace with the following code when 5.0 is released
//if (connectionStringName == AbpIdentityDbProperties.ConnectionStringName)
//{
// //.. return host's connection string
//}
return await Task.FromResult(connectionstring);
}
}
What specifically in the code do you need to see?
That is correct, you did not suggest that you did recomend that approach but if you read the entire thread it was suggested by someone else at Volo and did resolve that issue, so it appears that the connectionstring naming is not consistant so I will have to accomodate for that however, the issue is still not resolved with the LanguageTexts error I indicated I am getting which only happens when I log in as a Tenant user. Host user works fine. Please read thread to understand the distribution of our host vs tenant tables.
Thanks.
Hi,
But it's been suggested here that I not use the connection name string, but rather use the full namespace and Interface class name to resolve this issue.
So how do I resolve the issue I'm getting as I've tried everything that's been suggested with no success.
That resolved the issue with the code not finding the Users table but now I get an error on the "LanguageTexts" table as shown below. Just to clarify all the ABP base tables, including Saas, Identity server, users, etc are in a 'host' DB and the only tables in the 'tenant' DB are our application specific tables. So I want all things ABP module(pro and otherwise) to look at the host DB.
I tried adding the following code to resolve that connection string, but it did not work,.
case "Volo.Abp.LanguageManagement.EntityFrameworkCore.ILanguageManagementDbContext":
using (_currentTenant.Change(null))
{
connectionstring = await base.ResolveAsync(connectionStringName);
}
break;
After looking at this deeper, what you suggested as the solution is not accurate. The 'connectionstringname' that is being used by the MultiTenantConnectionStringResolver are not the value you suggest, thus making it difficult to point each (if I choose to) module's DBContext to a particular connection string.
So to summarize I am trying to put all the ABP tables that store Identity, LanguageManagement, permissions, Auditing, users, etc into the Host's DB and just have tennat tables (application specific) in their own DB's for each tenant.
There is no clear direction in the documents or previous support tickets that outline this so an actual real world example of this being implemented using ABP would be much appreaciated.
Thank you. That resolves my issue