- ABP Framework version: v6.0.0
- UI type: MVC
- DB provider: EF Core
- Tiered (MVC): yes
I have a requirement to resolve each tenant by a custom URL. I followed the blog post here https://blog.antosubash.com/posts/abp-extend-tenant-with-custom-host to add a custom field to y tenant table called "Host". When a user navigates to my solution on the URL, it will resolve the tenant automatically. I had a solution based on v4.4 which worked perfectly using this approach as documented in the blog. I upgraded the solution to v6 and the error being returned now is
Translation of 'EF.Property(EntityShaperExpression: Volo.Saas.Tenants.Tenant ValueBufferExpression: ProjectionBindingExpression: EmptyProjectionMember IsNullable: False , "Host")' failed. Either the query source is not an entity type, or the specified property does not exist on the entity type.
I then created a brand new v6.0.0 ABP solution and followed the blog thinking that I perhaps broke something in the upgrade. Unfortunately, it displays the same error.
The code fails as it is unable to find the new custom field added to the entity.
9 Answer(s)
-
0
Hi,
I think the following code is causing the problem.
var tenant = context.Tenants.Where(u => EF.Property<string>(u, "Host") == host);
I have a few questions so that I can better assist you with the problem:
1-) Is there a code like the picture below in the
YourProjectNameDbContextModelSnapshot.cs
class inside theYourProjectName.EntityFrameworkCore
orYourProjectName.EntityFrameworkCore.Migrations
project?2-) Is there a
Host
section as a separate column in theSaasTenants
table in the database used by the application?If your answer to these questions is yes, do you have a chance to send the content of your application's
**DbContext.cs
classes? -
0
Thats for the speedy reply. The answer to both your questions is yes. The *ModelSnapshot.cs class has the Host column specified on the Volo.Saas.Tenants.Tenant entity and the physical database column has the extra column.
This is the content of the DbContext.cs class
` namespace TaxDep.EntityFrameworkCore;
[ReplaceDbContext(typeof(IIdentityProDbContext))] [ReplaceDbContext(typeof(ISaasDbContext))] [ConnectionStringName("Default")] public class TaxDepDbContext : AbpDbContext
#region Entities from the modules /* Notice: We only implemented IIdentityProDbContext and ISaasDbContext * and replaced them for this DbContext. This allows you to perform JOIN * queries for the entities of these modules over the repositories easily. You * typically don't need that for other modules. But, if you need, you can * implement the DbContext interface of the needed module and use ReplaceDbContext * attribute just like IIdentityProDbContext and ISaasDbContext. * * More info: Replacing a DbContext of a module ensures that the related module * uses this DbContext on runtime. Otherwise, it will use its own DbContext class. */ // Identity public DbSet<IdentityUser> Users { get; set; } public DbSet<IdentityRole> Roles { get; set; } public DbSet<IdentityClaimType> ClaimTypes { get; set; } public DbSet<OrganizationUnit> OrganizationUnits { get; set; } public DbSet<IdentitySecurityLog> SecurityLogs { get; set; } public DbSet<IdentityLinkUser> LinkUsers { get; set; } // SaaS public DbSet<Tenant> Tenants { get; set; } public DbSet<Edition> Editions { get; set; } public DbSet<TenantConnectionString> TenantConnectionStrings { get; set; } #endregion public TaxDepDbContext(DbContextOptions<TaxDepDbContext> options) : base(options) { } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); /* Include modules to your migration db context */ builder.ConfigurePermissionManagement(); builder.ConfigureSettingManagement(); builder.ConfigureBackgroundJobs(); builder.ConfigureAuditLogging(); builder.ConfigureIdentityPro(); builder.ConfigureOpenIddict(); builder.ConfigureFeatureManagement(); builder.ConfigureLanguageManagement(); builder.ConfigureSaas(); builder.ConfigureTextTemplateManagement(); builder.ConfigureBlobStoring(); builder.ConfigureGdpr(); /* Configure your own tables/entities inside here */ //builder.Entity<YourEntity>(b => //{ // b.ToTable(TaxDepConsts.DbTablePrefix + "YourEntities", TaxDepConsts.DbSchema); // b.ConfigureByConvention(); //auto configure for the base class props // //... //}); builder.ConfigurePayment(); }
}
` As per the documentation, here is the setup of the *ExtensionMappings.cs
As per the documentation, here is the content of the *ExtensionConfigurator.cs class (inside Domain.Shared)
As mentioned, this worked as is in a previous version of ABP. I realise an easy workaround would be the adjust the TenantRepository to use a stored procedure instead, although it would be great to not have to create a workaround.
-
0
I tried to reproduce the problem with the information you provided, but unfortunately, I was unsuccessful.
I then created a brand new v6.0.0 ABP solution and followed the blog thinking that I perhaps broke something in the upgrade. Unfortunately, it displays the same error.
Any chance of submitting this application as a minimal-reproducible application?
-
0
Where can I upload the source to? I can send the entire application.
-
0
If the project is not private, you can create a new repository on GitHub or upload it to the cloud. If it is private, you can create a private repository on GitHub and add me.
https://github.com/berkansasmaz
-
0
I have pushed the repo to a public repository. It can be found here:
https://github.com/ImranHugo/abp-entity-sample.git
-
0
Thanks, I clone the repo, you can remove it for security reasons.
-
0
Thank you very much for the repeatable application. The problem is caused by a bug in
6.0.0
. This seems to have been resolved with this PR. So when we release6.0.0
patch version (soon), the problem will be solved. -
0
Thanks for the feedback. Looking forward to the patch.