Activities of "alexander.nikonov"

Mosf of the time - when we have a technical question - we are asked to either send the project source code or create the test version where the problem is reproduced.

The first one is not possible because of commercial nature of the project. The second one is very time consuming and is not possible too.

Yes, our solution is quite complex and we have some custom code on the top of ABP framework. But it would be great, if your support team devoted more time trying to understand the nature of the problem and analyze the fragments of the code shown in the message. Because often the answers are very short and meaningless - so we end up debugging out solution and looking at the downloaded ABP module source codes to resolve the problem ourselves.

p.ClrType == typeof(ExtraPropertyDictionary)

That was it. I was checking against string type only, would not expect such ClrType. Seems like I finally got rid of NVARCHAR. Thank you. I will keep this ticket open for some time until the migration is done...

And again you don't understand what I'm trying to say. I'm telling you that migration using a standard driver causes problem now. I have shown you the fragments of the code. Migration with Devart which has always been used never caused the problem. But now Devart cannot be used, they delay the NET7 support for month or so. You have published ABP7, but rely on Devart. Can you offer a working migration solution NOW?

Ok. But that was not my main question. My main question is why output generated by Devart differs from the standard one? They are supposed to be identical. Are you saying that output generated by standard driver is incorrect and cannot be used for Oracle migration??

Unfortunately, we don't have time and need to migrate now. So we need to use a generic Oracle driver. The script which is generated by the generic driver, looks weird, though - it suggests to replace VARCHAR fields in ABP tables with NVARCHAR. There are a lot of such changes. Could you please explain, why in a 7.0.1 test app you are suggesting to use NVARCHAR/NVARCHAR2 DB type:

but at the same time the suggested Devart-based DB configuration has the following options, i.e. the DB fields are generated as VARCHAR/VARCHAR2?

So currently the generated migration script has tons of suggested changes like this (it compares the previously created migration using Devart and a generic dviver generation now):

I've tried to get rid of NVARCHAR manually in the DB migration context:

    protected override void OnModelCreating(ModelBuilder builder)
    {
        //var config = Devart.Data.Oracle.Entity.Configuration.OracleEntityProviderConfig.Instance;
        //config.Workarounds.DisableQuoting = true;
        //config.CodeFirstOptions.UseNonLobStrings = true;
        //config.CodeFirstOptions.UseNonUnicodeStrings = true;

        base.OnModelCreating(builder);

        /* Include modules to your migration db context */

        builder.ConfigurePermissionManagement();
        builder.ConfigureSettingManagement();
        builder.ConfigureBackgroundJobs();
        builder.ConfigureAuditLogging();
        builder.ConfigureIdentityPro();
        builder.ConfigureIdentityServer();
        builder.ConfigureFeatureManagement();
        builder.ConfigureLanguageManagement();
        builder.ConfigureTextTemplateManagement();
        builder.ConfigureBlobStoring();
        builder.ConfigureSaas();
        
        foreach (var property in builder.Model.GetEntityTypes().SelectMany(e => e.GetProperties()).Where(p => p.ClrType == typeof(string)))
        {
            property.SetIsUnicode(false);
        }
    }

But it still generates me migration script with NVARCHAR/NVARCHAR2...

This does not help either:

    protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
    {
        configurationBuilder.DefaultTypeMapping<string>().IsUnicode(false);
    }
  • ABP Framework version: v5.1.2
  • UI type: Angular
  • DB provider: EF Core
  • Identity Server Separated (Angular)

I have a couple of issues / questions with the migration.

Server side: probably because of absent Devart Oracle driver which supports .NET 7.0+ the Add-Migration causes the following error (please note that we have set target=NET7 for all our projects):

Return type in method 'Devart.Common.Entity.c5.FindMapping(System.Type)' on type 'Devart.Common.Entity.c5' from assembly 'Devart.Data.Oracle.Entity.EFCore, Version=9.16.1434.0, Culture=neutral, PublicKeyToken=09af7300eec23701' is not compatible with base type method 'Microsoft.EntityFrameworkCore.Storage.RelationalTypeMappingSource.FindMapping(System.Type)'.

The Add-Migration itself with the standard driver completes successfully, but when I run Update-Database - very soon I end up with the errors related to Upper / Lower case in Table/Column names + quotes around those. We did not have such problems with Devart thanks to these options:

        var config = Devart.Data.Oracle.Entity.Configuration.OracleEntityProviderConfig.Instance;
        config.Workarounds.DisableQuoting = true;
        config.CodeFirstOptions.UseNonLobStrings = true;
        config.CodeFirstOptions.UseNonUnicodeStrings = true;

How to make a successful migration? Sorry - I cannot share the source code.

Client side: it is not clear which version of Angular should we use now, with ABP 7.0.1. We have had Angular 13 so far...I've tried to upgrade Angular after using abp update, but faced the compilation problem for our Angular packages, similar to these, but related to ng-bootstrap and other material components. So what Angular version should we use? Should we upgrade from version 13 and how to make it correct?

hi

I think there is no problem with this.

Restore my question points then please if not done yet.

Eventually I've resolved thie issue. I've split the shared project DbContexts into 2 - one contains the entities which are shared in the consuming project, another one contains the entities which use the same table as the entities in the consuming project. Please, replenish my point for this question.

I've tried to resolved the issue with the code below (separating DbContexts):

public static void ConfigureCoreInternal(this ModelBuilder builder, Action<CoreModelBuilderConfigurationOptions> optionsAction = null)
...

EntityFramework Module:

[DependsOn(typeof(CoreDomainModule), typeof(AbpEntityFrameworkCoreModule))]
public class CoreEntityFrameworkCoreModule : AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        context.Services.AddAbpDbContext<CoreDbContext>(options =>
        {
            options.AddDefaultRepository<ModuleLicence>();
            options.AddDefaultRepository<CompanyLicence>();
            options.AddDefaultRepository<Tenant>();
        });
    }
}

The method which does DB work:

public async Task<List<string>> GetAccessibleModulesAsync(int abxTenantId)
{
    using (var uow = _unitOfWorkManager.Begin())
    {
        var tenants = await _tenantRepository.GetQueryableAsync();
        var companyLicences = await _companyLicenceRepository.GetQueryableAsync();
        var moduleLicences = await _moduleLicenceRepository.GetQueryableAsync();

        var query = from tenant in tenants.Where(x => x.Id == abxTenantId).Take(1)
                    join companyLicence in companyLicences on tenant.CompanyId equals companyLicence.CompanyId
                    join moduleLicence in moduleLicences on companyLicence.LicenceId equals moduleLicence.LicenceId
                    select moduleLicence.ModuleId;

        return query.Distinct().ToList();
    }
}

Application Module where I add my custom class AbxPermissionChecker:

[DependsOn(...., typeof(CoreApplicationModule))]
public class CentralToolsApplicationModule : AbpModule
{
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        var configuration = context.Services.GetConfiguration();

        Configure<AbpAutoMapperOptions>(options =>
        {
            options.AddMaps<CentralToolsApplicationModule>();
        });

        ....
        context.Services.Replace(ServiceDescriptor.Transient<IPermissionChecker, AbxPermissionChecker>()); // REPLACING ABP PermissionChecker!
    }
}

But still getting the above exception

What is a proper way of isolating entities in the DbContext of the project which is shared? Maybe this is the only root of the problem?

  • ABP Framework version: v5.1.2
  • UI type: Angular
  • DB provider: EF Core
  • Identity Server Separated (Angular)

I am trying to create a custom implementation of IPermissionChecker in the shared project and consume this implementation in several projects. Currently I'm having the problem with this implementation. Here is the checker:

[Dependency(ReplaceServices = false)]
public class AbxPermissionChecker : IPermissionChecker
{
    private PermissionChecker _abpPermissionChecker;
    private IServiceProvider _serviceProvider;
    private readonly ILicencePermissionChecker _licencePermissionChecker;

    public AbxPermissionChecker
    (
        PermissionChecker abpPermissionChecker,
        IServiceProvider serviceProvider,
        ILicencePermissionChecker licencePermissionChecker
    )
    {
        _abpPermissionChecker = abpPermissionChecker;
        _serviceProvider = serviceProvider;
        _licencePermissionChecker = licencePermissionChecker;
    }

    public async Task<bool> IsGrantedAsync(ClaimsPrincipal claimsPrincipal, string name)
    {
        using var scope = _serviceProvider.CreateScope();

        var abxRequestContext = scope.ServiceProvider.GetRequiredService<IAbxRequestContext>();

        return await _licencePermissionChecker.IsGrantedAsync(abxRequestContext.AbxTenantId, abxRequestContext.AbxModuleId) && await _abpPermissionChecker.IsGrantedAsync(claimsPrincipal, name);
    }

    public Task<bool> IsGrantedAsync(string name)
    {
        return _abpPermissionChecker.IsGrantedAsync(name);
    }

    public Task<MultiplePermissionGrantResult> IsGrantedAsync(string[] names)
    {
        return _abpPermissionChecker.IsGrantedAsync(names);
    }

    public Task<MultiplePermissionGrantResult> IsGrantedAsync(ClaimsPrincipal claimsPrincipal, string[] names)
    {
        return _abpPermissionChecker.IsGrantedAsync(claimsPrincipal, names);
    }
}

public class PermissionManager : DomainService
{
    private readonly IRepository<Tenant, int> _tenantRepository;
    private readonly IRepository<ModuleLicence> _moduleLicenceRepository;
    private readonly IRepository<CompanyLicence> _companyLicenceRepository;

    public PermissionManager
    (
        IRepository<Tenant, int> tenantRepository,
        IRepository<ModuleLicence> moduleLicenceRepository,
        IRepository<CompanyLicence> companyLicenceRepository
    )
    {
        _tenantRepository = tenantRepository;
        _moduleLicenceRepository = moduleLicenceRepository;
        _companyLicenceRepository = companyLicenceRepository;
    }

    public async Task<List<string>> GetAccessibleModulesAsync(int abxTenantId)
    {
        var tenants = await _tenantRepository.GetQueryableAsync();
        var companyLicences = await _companyLicenceRepository.GetQueryableAsync();
        var moduleLicences = await _moduleLicenceRepository.GetQueryableAsync();

        var query = from tenant in tenants.Where(x => x.Id == abxTenantId).Take(1)
                    join companyLicence in companyLicences on tenant.CompanyId equals companyLicence.CompanyId
                    join moduleLicence in moduleLicences on companyLicence.LicenceId equals moduleLicence.LicenceId
                    select moduleLicence.ModuleId;

        return query.Distinct().ToList();
    }
}

The exception I'm getting in the consuming project when accessing PermissionManager method:

Autofac.Core.DependencyResolutionException: An exception was thrown while activating Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.AbpApplicationConfigurationController -> Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations.AbpApplicationConfigurationAppService -> AbxEps.CT.Core.Permissions.AbxPermissionChecker -> AbxEps.CT.Core.Permissions.AbxLicencePermissionChecker -> AbxEps.CT.Core.Permissions.PermissionManager. ---> Autofac.Core.DependencyResolutionException: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'AbxEps.CT.Core.Permissions.PermissionManager' can be invoked with the available services and parameters: Cannot resolve parameter 'Volo.Abp.Domain.Repositories.IRepository2[AbxEps.CT.Core.Tenants.Tenant,System.Int32] tenantRepository' of constructor 'Void .ctor(Volo.Abp.Domain.Repositories.IRepository2[AbxEps.CT.Core.Tenants.Tenant,System.Int32], Volo.Abp.Domain.Repositories.IRepository1[AbxEps.CT.Core.ModuleLicences.ModuleLicence], Volo.Abp.Domain.Repositories.IRepository1[AbxEps.CT.Core.CompanyLicences.CompanyLicence])'.

Now let me explain what I'm trying to achieve. CoreDbContext in the shared project contains SIMPLIFIED models of entities which are ALREADY bound in the consuming project. Since I cannot bind the model to the same table name twice in the same DbContext as well as I don't want to MOVE a complex model binding from consuming project to the shared project, I decided to use two independent DbContext:

public static void ConfigureCore(
    this ModelBuilder builder,
    Action<CoreModelBuilderConfigurationOptions> optionsAction = null
) {
    builder.Entity<CompanyLicence>(b =>
    {
        b.ToTable("CT_CA_COMP_LIC", CentralToolsConsts.DbSchema);
        .... simplified binding
    }

public static void ConfigureConsuming(
    this ModelBuilder builder,
    Action<ConsumingModelBuilderConfigurationOptions> optionsAction = null
) {
    builder.Entity<CompanyLicence>(b =>
    {
        b.ToTable("CT_CA_COMP_LIC", CentralToolsConsts.DbSchema);
        .... advanced binding
    }
Showing 1 to 10 of 141 entries
Made with ❤️ on ABP v8.3.0-preview Updated on July 04, 2024, 07:07