Open Closed

EntityFrameworkCore.Triggered and ABP? #1417


User avatar
0
hansmogren created

I want to use https://github.com/koenbeuk/EntityFrameworkCore.Triggered in my ABP solution but I can't figure out how to register the triggers with my AbpDbContext.

This is what the documentation for EntityFrameworkCore.Triggered suggests:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services
            .AddDbContext(options => {
                options.UseTriggers(triggerOptions => {
                    triggerOptions.AddTrigger();
                });
            })
    }
}

How can I use this library with with ABP?


10 Answer(s)
  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    Open *.EntityFrameworkCoreModule and find Configure<AbpDbContextOptions>:

    Configure<AbpDbContextOptions>(options =>
    {
        /* The main point to change your DBMS.
         * See also MyProjectNameMigrationsDbContextFactory for EF Core tooling. */
        options.UseSqlServer();
    
        options.Configure(c =>
        {
            c.DbContextOptions.UseTriggers();
        });
    });
    
  • User Avatar
    0
    hansmogren created

    Thanks! However, when I try that I get an error on application start:

    An unhandled exception occurred while processing the request.
    InvalidOperationException: No database provider has been configured for this DbContext. A provider can be configured by overriding the 'DbContext.OnConfiguring' method or by using 'AddDbContext' on the application service provider. If 'AddDbContext' is used, then also ensure that your DbContext type accepts a DbContextOptions<TContext> object in its constructor and passes it to the base constructor for DbContext.

    Microsoft.EntityFrameworkCore.Internal.DbContextServices.Initialize(IServiceProvider scopedProvider, IDbContextOptions contextOptions, DbContext context)

    Stack trace:

    <br>

    InvalidOperationException: No database provider has been configured for this DbContext. A provider can be configured by overriding the 'DbContext.OnConfiguring' method or by using 'AddDbContext' on the application service provider. If 'AddDbContext' is used, then also ensure that your DbContext type accepts a DbContextOptions object in its constructor and passes it to the base constructor for DbContext.
    
        Microsoft.EntityFrameworkCore.Internal.DbContextServices.Initialize(IServiceProvider scopedProvider, IDbContextOptions contextOptions, DbContext context)
        Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
        Microsoft.EntityFrameworkCore.DbContext.get_ChangeTracker()
        Volo.Abp.EntityFrameworkCore.AbpDbContext.Initialize(AbpEfCoreDbContextInitializationContext initializationContext)
        Volo.Abp.Uow.EntityFrameworkCore.UnitOfWorkDbContextProvider.CreateDbContextAsync(IUnitOfWork unitOfWork, string connectionStringName, string connectionString)
        Volo.Abp.Uow.EntityFrameworkCore.UnitOfWorkDbContextProvider.GetDbContextAsync()
        Volo.Abp.Domain.Repositories.EntityFrameworkCore.EfCoreRepository.GetDbSetAsync()
        Volo.Abp.LanguageManagement.EntityFrameworkCore.EfCoreLanguageRepository.GetListAsync(bool isEnabled)
        Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous(IInvocation invocation, IInvocationProceedInfo proceedInfo)
        Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue.ProceedAsync()
        Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
        Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter.InterceptAsync(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func> proceed)
        Volo.Abp.LanguageManagement.DatabaseLanguageProvider.oBPl0rvdv()
        Volo.Abp.Caching.DistributedCache.GetOrAddAsync(TCacheKey key, Func> factory, Func optionsFactory, Nullable hideErrors, bool considerUow, CancellationToken token)
        Volo.Abp.LanguageManagement.DatabaseLanguageProvider.GetLanguagesAsync()
        Microsoft.AspNetCore.RequestLocalization.DefaultAbpRequestLocalizationOptionsProvider.GetLocalizationOptionsAsync()
        Microsoft.AspNetCore.RequestLocalization.AbpRequestLocalizationMiddleware.InvokeAsync(HttpContext context, RequestDelegate next)
        Microsoft.AspNetCore.Builder.UseMiddlewareExtensions+<>c__DisplayClass6_1+<b__1>d.MoveNext()
        Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
    
    
  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Try:

    Configure<AbpDbContextOptions>(options =>
    {
        options.Configure(c =>
        {
            c.UseSqlServer();
            c.DbContextOptions.UseTriggers();
        });
    });
    
  • User Avatar
    0
    hansmogren created

    Thanks, that change made the trigger be registered and triggered.

    However the dependency injection failed while instantiating my trigger class. I am injecting an IRepository into it and got an exception:
    System.InvalidOperationException: 'Unable to resolve service for type 'MyProjectName.IMyEntityRepository' while attempting to activate 'MyProjectName.BeforeSaveTrigger'.'

    I solved this by including the line
    t.UseApplicationScopedServiceProviderAccessor(_ => context.Services.GetServiceProviderOrNull()); as below since the the documentation at https://github.com/koenbeuk/EntityFrameworkCore.Triggered/wiki/Dependency-injection mentions this solution:

    Configure a method that returns the current relevant ServiceProvider. This can be done by providing a method through: triggerOptions.UseApplicationScopedServiceProviderAccessor(sp => ...). The first argument will be either the application ServiceProvider if available or otherwise the internal service provider.

    Does this seem like a reasonable solution or will it break something?

                options.Configure(c =>
                {
                    c.UseSqlServer();
                    c.DbContextOptions.UseTriggers(t =>
                    {
                        t.UseApplicationScopedServiceProviderAccessor(_ => context.Services.GetServiceProviderOrNull());
                        t.AddTrigger<BeforeSaveTrigger>();
                    });
                });
    
  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    hi,

    This way will be better

    c.DbContextOptions.UseTriggers(t =>
    {
        t.UseApplicationScopedServiceProviderAccessor(_ => _.GetRequiredService<IHttpContextAccessor>().HttpContext?.RequestServices);
    });
    
  • User Avatar
    0
    hansmogren created
    c.DbContextOptions.UseTriggers(t => 
    { 
        t.UseApplicationScopedServiceProviderAccessor(_ => _.GetRequiredService<IHttpContextAccessor>().HttpContext?.RequestServices); 
    }); 
    

    Doing this way I get System.InvalidOperationException: 'No service for type 'Microsoft.AspNetCore.Http.IHttpContextAccessor' has been registered.' on application start.

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    After my test, the following code is ok.

    Configure<AbpDbContextOptions>(options =>
    {
    
        options.Configure(c =>
        {
            c.UseSqlServer();
            c.DbContextOptions.UseTriggers(t =>
            {
                t.UseApplicationScopedServiceProviderAccessor(_ => _.CreateScope().ServiceProvider);
            });
    
        });
    });
    
  • User Avatar
    0
    hansmogren created

    After my test, the following code is ok.

    Sorry, but I get System.InvalidOperationException: 'Unable to resolve service for type 'MyProjectName.IMyEntityRepository' while attempting to activate 'MyProjectName.BeforeSaveTrigger'.' doing it this way as well.

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Can you share the full logs?

  • User Avatar
    0
    ServiceBot created
    Support Team Automatic process manager

    This question has been automatically marked as stale because it has not had recent activity.

Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
Do you need assistance from an ABP expert?
Schedule a Meeting
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v9.2.0-preview. Updated on March 13, 2025, 04:08