Base solution for your next web application
Open Closed

the ticket has been closed #12540 #12543


User avatar
0
gtc created

" Hi @gtc Thank you for reporting this issue. Since you mentioned that the same code works on ASP.NET Zero v8 but returns error 500 on v9, this looks like it may be related to a breaking change or a serialization difference between the versions. To help us investigate further, could you please provide the following details:

  1. The exact ASP.NET Zero version you are using on v9.
  2. The full exception details stack trace from your server logs (the 500 error in Swagger usually hides the real cause).
  3. The code of your GetControleEAForViewDto class (or at least its properties). Sometimes circular references or unsupported property types can cause serialization errors. In many cases, error 500 in Swagger while data is visible in debug mode points to a JSON serialization problem (e.g., reference loops, unsupported property types, or large data structures). Once we have the stack trace, we can confirm whether this is the case." Hi, thank you for your feedback 1/ version ASP.NET CORE & Angular .NET 9.0 v14.1.0 2/ log : INFO 2025-09-24 16:00:34,447 [20 ] Microsoft.AspNetCore.Hosting.Diagnostics - Request starting HTTP/2 GET https://localhost:44301/api/services/app/ControleEAs/GetAll - - - INFO 2025-09-24 16:00:34,450 [20 ] ft.AspNetCore.Routing.EndpointMiddleware - Executing endpoint 'Portail_GTC.EA.ControleEAsAppService.GetAll (Portail_GTC.Application)' INFO 2025-09-24 16:00:34,466 [20 ] c.Infrastructure.ControllerActionInvoker - Route matched with {area = "app", action = "GetAll", controller = "ControleEAs"}. Executing controller action with signature System.Threading.Tasks.Task1[Abp.Application.Services.Dto.PagedResultDto1[Portail_GTC.EA.Dtos.GetControleEAForViewDto]] GetAll(Portail_GTC.EA.Dtos.GetAllControleEAsInput) on controller Portail_GTC.EA.ControleEAsAppService (Portail_GTC.Application). ERROR 2025-09-24 16:00:47,908 [19 ] Microsoft.EntityFrameworkCore.Update - An exception occurred in the database while saving changes for context type 'Portail_GTC.EA.EA_ProdbContext'. System.InvalidOperationException: The configured execution strategy 'SqlServerRetryingExecutionStrategy' does not support user-initiated transactions. Use the execution strategy returned by 'DbContext.Database.CreateExecutionStrategy()' to execute all the operations in the transaction as a retriable unit. at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.OnFirstExecution() at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func4 operation, Func4 verifySucceeded, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) System.InvalidOperationException: The configured execution strategy 'SqlServerRetryingExecutionStrategy' does not support user-initiated transactions. Use the execution strategy returned by 'DbContext.Database.CreateExecutionStrategy()' to execute all the operations in the transaction as a retriable unit. at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.OnFirstExecution() at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func4 operation, Func4 verifySucceeded, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) ERROR 2025-09-24 16:00:48,452 [19 ] Mvc.ExceptionHandling.AbpExceptionFilter - The configured execution strategy 'SqlServerRetryingExecutionStrategy' does not support user-initiated transactions. Use the execution strategy returned by 'DbContext.Database.CreateExecutionStrategy()' to execute all the operations in the transaction as a retriable unit. System.InvalidOperationException: The configured execution strategy 'SqlServerRetryingExecutionStrategy' does not support user-initiated transactions. Use the execution strategy returned by 'DbContext.Database.CreateExecutionStrategy()' to execute all the operations in the transaction as a retriable unit. at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.OnFirstExecution() at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func4 operation, Func4 verifySucceeded, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) at Abp.EntityFrameworkCore.AbpDbContext.SaveChangesAsync(CancellationToken cancellationToken) at Abp.EntityFrameworkCore.Uow.EfCoreUnitOfWork.SaveChangesAsync() at Abp.EntityFrameworkCore.Uow.EfCoreUnitOfWork.CompleteUowAsync() at Abp.Domain.Uow.UnitOfWorkBase.CompleteAsync() at Abp.AspNetCore.Mvc.Uow.AbpUowActionFilter.OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) INFO 2025-09-24 16:00:48,574 [19 ] .Mvc.Infrastructure.ObjectResultExecutor - Executing ObjectResult, writing value of type 'Abp.Web.Models.AjaxResponse'. INFO 2025-09-24 16:00:48,579 [19 ] c.Infrastructure.ControllerActionInvoker - Executed action Portail_GTC.EA.ControleEAsAppService.GetAll (Portail_GTC.Application) in 14113.2001ms INFO 2025-09-24 16:00:48,580 [19 ] ft.AspNetCore.Routing.EndpointMiddleware - Executed endpoint 'Portail_GTC.EA.ControleEAsAppService.GetAll (Portail_GTC.Application)' INFO 2025-09-24 16:00:48,583 [19 ] Microsoft.AspNetCore.Hosting.Diagnostics - Request finished HTTP/2 GET https://localhost:44301/api/services/app/ControleEAs/GetAll - 500 - application/json;+charset=utf-8 14134.4313ms

3/ I don't think it's due to the JSON format. I tried a simple method and no problem.

dditional information. I am running the stored procedure in a second DB context connected to another database.

code source repository :

using Abp.Data; using Abp.Domain.Repositories; using Abp.Domain.Uow; using Abp.EntityFrameworkCore; using Abp.MultiTenancy; using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; using Portail_GTC.EA; using Portail_GTC.EA.entity; using Portail_GTC.EA.Repository; using Portail_GTC.EntityFrameworkCore.Repositories; using System; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Linq; using System.Threading.Tasks;

namespace Portail_GTC.Repository { public class RepositoryControleEA : EA_ProdRepositoryBase<ControleEA>, IRepositoryControleEA { private readonly IActiveTransactionProvider _transactionProvider; private readonly IUnitOfWorkManager _unitOfWorkManager;

public RepositoryControleEA(
    IDbContextProvider&lt;EA_ProdbContext&gt; dbContextProvider,
    IActiveTransactionProvider transactionProvider,
    IUnitOfWorkManager unitOfWorkManager)
    : base(dbContextProvider)
{
    _transactionProvider = transactionProvider;
    _unitOfWorkManager = unitOfWorkManager;
}

/// &lt;summary&gt;
/// Exécute la procédure stockée wb_ControlesRT02 et retourne les résultats.
/// &lt;/summary&gt;
public async Task&lt;List&lt;ControleEA&gt;> GetAllControleEAAsync()
{
    var result = new List&lt;ControleEA&gt;();

    // Récupère la connexion et la transaction EF Core
    var connection = GetContext().Database.GetDbConnection();
    var transaction = GetActiveTransaction();

    using (var command = connection.CreateCommand())
    {
        command.CommandText = "wb_ControlesRT02";
        command.CommandType = CommandType.StoredProcedure;
        command.Transaction = transaction;

        // Ajout des paramètres
        command.Parameters.Add(new SqlParameter("@Exploitant", -1));
        command.Parameters.Add(new SqlParameter("@Constructeur", -1));
        command.Parameters.Add(new SqlParameter("@NumLot", DBNull.Value));
        command.Parameters.Add(new SqlParameter("@NumExploitant", DBNull.Value));
        command.Parameters.Add(new SqlParameter("@NumConstructeur", DBNull.Value));
        command.Parameters.Add(new SqlParameter("@Nomclient", DBNull.Value));
        command.Parameters.Add(new SqlParameter("@CP", DBNull.Value));
        command.Parameters.Add(new SqlParameter("@Prestataire", -1));
        command.Parameters.Add(new SqlParameter("@Debut", new DateTime(2023, 12, 31)));
        command.Parameters.Add(new SqlParameter("@Fin", new DateTime(2024, 12, 31)));
        command.Parameters.Add(new SqlParameter("@Classe", DBNull.Value));
        command.Parameters.Add(new SqlParameter("@Approuve", 1));
        command.Parameters.Add(new SqlParameter("@DateAllSearch", 3));

        // EF Core ouvre automatiquement la connexion si nécessaire
        if (connection.State != ConnectionState.Open)
            await connection.OpenAsync();

        using (var reader = await command.ExecuteReaderAsync())
        {
            while (await reader.ReadAsync())
            {
                result.Add(MapControleEA(reader));
            }
        }
    }

    return result;
}

/// &lt;summary&gt;
/// Map un DbDataReader vers l'entité ControleEA
/// &lt;/summary&gt;
private ControleEA MapControleEA(DbDataReader reader)
{
    return new ControleEA
    {
        IdOrdreMission = Convert.ToInt64(reader["IdOrdreMission"]),
        Constructeur = reader["Constructeur"]?.ToString(),
        NumExploitant = reader["NumExploitant"]?.ToString(),
        NumeroLot = reader["NumeroLot"]?.ToString(),
        NumClient = reader["NumClient"]?.ToString(),
        NomClient = reader["NomClient"]?.ToString(),
        CodePostal = reader["CodePostal"]?.ToString(),
        Exploitant = reader["Exploitant"]?.ToString(),
        Prestataire = reader["Prestataire"]?.ToString(),
        DateDeControle = (DateTime)(reader["DateDeControle"] != DBNull.Value ? Convert.ToDateTime(reader["DateDeControle"]) : (DateTime?)null),
        // DateDeControle = reader["DateDeControle"] != DBNull.Value ? Convert.ToDateTime(reader["DateDeControle"]) : (DateTime?)null,
        DateApprobation = reader["DateApprobation"]?.ToString()
    };
}

/// &lt;summary&gt;
/// Retourne la transaction active pour le DbCommand
/// &lt;/summary&gt;
private DbTransaction GetActiveTransaction()
{
    return (DbTransaction)_transactionProvider.GetActiveTransaction(new ActiveTransactionProviderArgs
    {
        {"ContextType", typeof(EA_ProdbContext) },
        {"MultiTenancySide", MultiTenancySide }
    });
}

} code source service

public virtual async Task&lt;PagedResultDto<GetControleEAForViewDto>> GetAll(GetAllControleEAsInput input) { var AllControleEA = await _repositoryControleEA.GetAllControleEAAsync(); var filteredControleEA = AllControleEA .WhereIf(!string.IsNullOrWhiteSpace(input.Filter), e => false || e.Constructeur.Contains(input.Filter) || e.NumExploitant.Contains(input.Filter) || e.NumeroLot.Contains(input.Filter) || e.NumClient.Contains(input.Filter) || e.NomClient.Contains(input.Filter) || e.CodePostal.Contains(input.Filter) || e.Exploitant.Contains(input.Filter) || e.Prestataire.Contains(input.Filter) || e.DateApprobation.Contains(input.Filter)) .WhereIf(input.MinIdOrdreMissionFilter != null, e => e.IdOrdreMission >= input.MinIdOrdreMissionFilter) .WhereIf(input.MaxIdOrdreMissionFilter != null, e => e.IdOrdreMission <= input.MaxIdOrdreMissionFilter) .WhereIf(!string.IsNullOrWhiteSpace(input.ConstructeurFilter), e => e.Constructeur.ToLower().Contains(input.ConstructeurFilter.ToLower())) .WhereIf(!string.IsNullOrWhiteSpace(input.NumExploitantFilter), e => e.NumExploitant.ToLower().Contains(input.NumExploitantFilter.ToLower())) .WhereIf(!string.IsNullOrWhiteSpace(input.NumeroLotFilter), e => e.NumeroLot.ToLower().Contains(input.NumeroLotFilter.ToLower())) .WhereIf(!string.IsNullOrWhiteSpace(input.NumClientFilter), e => e.NumClient.ToLower().Contains(input.NumClientFilter)) .WhereIf(!string.IsNullOrWhiteSpace(input.NomClientFilter), e => e.NomClient.ToLower().Contains(input.NomClientFilter)) .WhereIf(!string.IsNullOrWhiteSpace(input.CodePostalFilter), e => e.CodePostal.ToLower().Contains(input.CodePostalFilter)) .WhereIf(!string.IsNullOrWhiteSpace(input.ExploitantFilter), e => e.Exploitant.ToLower().Contains(input.ExploitantFilter)) .WhereIf(!string.IsNullOrWhiteSpace(input.PrestataireFilter), e => e.Prestataire.ToLower().Contains(input.PrestataireFilter)) .WhereIf(input.MinDateDeControleFilter != null, e => e.DateDeControle >= input.MinDateDeControleFilter) .WhereIf(input.MaxDateDeControleFilter != null, e => e.DateDeControle <= input.MaxDateDeControleFilter) .WhereIf(!string.IsNullOrWhiteSpace(input.DateApprobationFilter), e => e.DateApprobation.Contains(input.DateApprobationFilter)); //var pagedAndFilteredControleEAs = filteredControleEA // .OrderBy(input.Sorting ?? "id asc") // .PageBy(input); var pagedAndFilteredTestcontroleEAs = filteredControleEA.AsQueryable() .OrderBy(input.Sorting ?? "id asc") .PageBy(input); var controleEAs = from o in pagedAndFilteredTestcontroleEAs select new { o.IdOrdreMission, o.Constructeur, o.NumeroLot, o.NumExploitant, o.NumClient, o.CodePostal, o.NomClient, o.Exploitant, o.Prestataire, o.DateDeControle, o.DateApprobation, Id = o.Id }; // var totalCount = await filteredControleEA.CountAsync(); var totalCount = filteredControleEA.Count(); var dbList = controleEAs.ToList(); //var dbList = controleEAs.ToList(); var results = new List&lt;GetControleEAForViewDto>(); foreach (var o in dbList) { var res = new GetControleEAForViewDto() { ControleEA = new ControleEADto { IdOrdreMission = o.IdOrdreMission, Constructeur = o.Constructeur, NumeroLot = o.NumeroLot, NumExploitant = o.NumExploitant, NumClient = o.NumClient, CodePostal = o.CodePostal, NomClient = o.NomClient, Exploitant = o.Exploitant, Prestataire = o.Prestataire, DateDeControle = o.DateDeControle, DateApprobation = o.DateApprobation, Id = o.Id, } }; results.Add(res); } return new PagedResultDto&lt;GetControleEAForViewDto>( totalCount, results ); }

Markdown is supported
Copy & paste or drag & drop images (max 30 MB per image)

6 Answer(s)
  • User Avatar
    0
    oguzhanagir created
    Support Team

    Hi @gtc

    Starting with EF Core 7+ (and ASP.NET Zero v14.1), the SqlServerRetryingExecutionStrategy is not compatible with manual transactions. When you get a transaction via GetActiveTransaction() and assign it to the DbCommand, EF Core throws an error saying:

    “The configured execution strategy 'SqlServerRetryingExecutionStrategy' does not support user-initiated transactions.”

    Remove the transaction

    If your stored procedure only performs read operations or works independently, you don’t need a transaction at all.

    using (var command = connection.CreateCommand())
    {
        command.CommandText = "wb_ControlesRT02";
        command.CommandType = CommandType.StoredProcedure;
        // command.Transaction = transaction;   <-- remove this
    
        // parameters...
    }
    

    This should fix the HTTP 500 error.

    Wrap the call with ExecutionStrategy (retry safe)

    If you really need a transaction, you must wrap the operation in ExecutionStrategy.ExecuteAsync:

    var strategy = GetContext().Database.CreateExecutionStrategy();
    
    return await strategy.ExecuteAsync(async () =>
    {
        var result = new List<ControleEA>();
        var connection = GetContext().Database.GetDbConnection();
    
        using (var command = connection.CreateCommand())
        {
            command.CommandText = "wb_ControlesRT02";
            command.CommandType = CommandType.StoredProcedure;
            // Prefer avoiding manual transactions here
            // command.Transaction = transaction;
    
            // parameters...
    
            if (connection.State != ConnectionState.Open)
                await connection.OpenAsync();
    
            using (var reader = await command.ExecuteReaderAsync())
            {
                while (await reader.ReadAsync())
                {
                    result.Add(MapControleEA(reader));
                }
            }
        }
    
        return result;
    });
    

    Run the second DbContext outside UnitOfWork

    Since you are already using a second DbContext (EA_ProdbContext), trying to attach it to the same UnitOfWork transaction causes the failure. The cleanest approach is to run this DbContext independently (no manual transaction binding).

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    oguzhanagir created
    Support Team

    Hi @gtc

    Here is the root cause of the problem: When you call a method in an ApplicationService, ASP.NET Zero typically starts a database transaction automatically. Your code then attempts to run a new ExecutionStrategy, which has retry capabilities, inside this pre-existing transaction. The SqlServerRetryingExecutionStrategy does not support externally initiated transactions (referred to as "user-initiated transactions"), which leads to this exception.

    There are two primary solutions. For your specific case, the first method is the most appropriate.

    Disable the Unit of Work

    The stored procedure you are calling (wb_ControlesRT02) is used only for reading data. Therefore, this operation does not need to be wrapped in a database transaction. The cleanest solution is to disable the Unit of Work for the specific method that triggers this call.

    To do this, add the [UnitOfWork(IsDisabled = true)] attribute to the Application Service method that calls your repository method.

    Example:

    Let's assume you have a service named ControleEAAppService with a method inside it like this:

    
    public class ControleEAAppService : Portail_GTCAppServiceBase, IControleEAAppService
    {
        private readonly IRepositoryControleEA _repositoryControleEA;
    
        public ControleEAAppService(IRepositoryControleEA repositoryControleEA)
        {
            _repositoryControleEA = repositoryControleEA;
        }
    
        // ADD THIS ATTRIBUTE
        [UnitOfWork(IsDisabled = true)] 
        public async Task<List<ControleEADto>> GetAllControles()
        {        
            // ...
        }
    }
    

    After making this change, you can simplify your repository code. You may no longer need to manually invoke the ExecutionStrategy, as the conflicting transaction will no longer exist. However, your existing code will still work if you wish to keep the retry logic specifically for that database call.

    Simplify the Code with FromSqlRaw

    Your current code manually creates ADO.NET commands. EF Core offers much simpler methods like FromSqlRaw or ExecuteSqlRaw to handle this. This not only cleans up your code but also makes it easier to manage these types of errors.

    After adding [UnitOfWork(IsDisabled = true)] to your service, I highly recommend rewriting your repository method as follows:

    public class RepositoryControleEA : EA_ProdRepositoryBase<ControleEA>, IRepositoryControleEA
    {
        public RepositoryControleEA(IDbContextProvider<EA_ProdbContext> dbContextProvider)      
            : base(dbContextProvider)
        {   
        }
      
        public virtual async Task<IQueryable<ControleEA>> GetAllControleEAAsync()
        {
            // parameters
            var parameters = new[]
            {
                new SqlParameter("@Exploitant", -1),
                new SqlParameter("@Constructeur", -1),
                new SqlParameter("@NumLot", DBNull.Value),
                new SqlParameter("@NumExploitant", DBNull.Value),
                new SqlParameter("@NumConstructeur", DBNull.Value),
                new SqlParameter("@Nomclient", DBNull.Value),
                new SqlParameter("@CP", DBNull.Value),
                new SqlParameter("@Prestataire", -1),
                new SqlParameter("@Debut", new DateTime(2024, 08, 31)),
                new SqlParameter("@Fin", new DateTime(2024, 12, 31)),
                new SqlParameter("@Classe", DBNull.Value),
                new SqlParameter("@Approuve", 1),
                new SqlParameter("@DateAllSearch", 3)
            };
    
            // Call the stored procedure directly from the context
            var result = await GetContext().ControleEAs // Your DbSet name might be different
                                           .FromSqlRaw("EXEC wb_ControlesRT02 @Exploitant, @Constructeur, @NumLot, @NumExploitant, @NumConstructeur, @Nomclient, @CP, @Prestataire, @Debut, @Fin, @Classe, @Approuve, @DateAllSearch", parameters)
                                           .ToListAsync();
    
            return result.AsQueryable();
        }
    }
    

    If these suggestions do not solve your problem, please do not hesitate to contact us.

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    gtc created

    Hello, the error message "SqlServerRetryingExecutionStrategy" disappeared after modifying the following files: EA_ProdbContext, EA_ProdbContextConfigurer, EA_ProdbContextFactory, Portail_GTCEntityFrameworkCoreModule., EA_ProdbRepositoryBase

    Now the problem we have is that it looks for the procedure stored in the default database and not the second one. Could you tell me if according to my code it is correct. And if there are other parameters to configure? Thank you.

    namespace Portail_GTC.repository
    {
        public class ControleEARepository : EA_ProdbRepositoryBase<ControleEA>,IControleEARepository
        {
          //  private readonly EA_ProdbContext _dbContext;
            private readonly IDbContextProvider<EA_ProdbContext> _dbContextProvider;
    
            public ControleEARepository(IDbContextProvider<EA_ProdbContext> dbContextProvider)
                : base(dbContextProvider)
            {
    
                _dbContextProvider = dbContextProvider ?? throw new ArgumentNullException(nameof(dbContextProvider));
            }
    
            public async Task<IQueryable<ControleEA>> GetControlesAsync()
            {
                try
                {
                    // parameters
                    var parameters = new[]
                    {
                new SqlParameter("@Exploitant", -1),
                new SqlParameter("@Constructeur", -1),
                new SqlParameter("@NumLot", DBNull.Value),
                new SqlParameter("@NumExploitant", DBNull.Value),
                new SqlParameter("@NumConstructeur", DBNull.Value),
                new SqlParameter("@Nomclient", DBNull.Value),
                new SqlParameter("@CP", DBNull.Value),
                new SqlParameter("@Prestataire", -1),
                new SqlParameter("@Debut", new DateTime(2024, 08, 31)),
                new SqlParameter("@Fin", new DateTime(2024, 12, 31)),
                new SqlParameter("@Classe", DBNull.Value),
                new SqlParameter("@Approuve", 1),
                new SqlParameter("@DateAllSearch", 3)
            };
    
                    // Call the stored procedure directly from the context
                    var context = await _dbContextProvider.GetDbContextAsync();
                    var result = await context.ControleEAs // Your DbSet name might be different
                                                   .FromSqlRaw("EXEC wb_ControlesRT02 @Exploitant, @Constructeur, @NumLot, @NumExploitant, @NumConstructeur, @Nomclient, @CP, @Prestataire, @Debut, @Fin, @Classe, @Approuve, @DateAllSearch", parameters)
                                                   .ToListAsync();
    
                    return result.AsQueryable();
                }
                catch (Exception ex)
                {
    
                    throw;
                }
              
            }
        }
    }
    
    

    second dbcontext

    namespace Portail_GTC.EntityFrameworkCore
    {
        public class EA_ProdbContext : AbpDbContext
        {
        // Déclare tes tables ici
        public virtual DbSet<Personne> Personnes { get; set; }
        public virtual DbSet<ControleEA> ControleEAs { get; set; }
    
            public EA_ProdbContext(DbContextOptions<EA_ProdbContext> options)
                : base(options)
            {
            }
    
            protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
                base.OnModelCreating(modelBuilder);
    
               
            }
        }
    }
    
    

    file : EA_ProdbRepositoryBase

    using Abp.EntityFrameworkCore;
    using Abp.EntityFrameworkCore.Repositories;
    namespace Portail_GTC.EntityFrameworkCore.Repositories;
    /// <summary>
    /// Base class for custom repositories of the application.
    /// </summary>
    /// <typeparam name="TEntity">Entity type</typeparam>
    /// <typeparam name="TPrimaryKey">Primary key type of the entity</typeparam>
    public abstract class EA_ProdbRepositoryBase<TEntity, TPrimaryKey> : EfCoreRepositoryBase<EA_ProdbContext, TEntity, TPrimaryKey>
        where TEntity : class, IEntity<TPrimaryKey>
    {
        protected EA_ProdbRepositoryBase(IDbContextProvider<EA_ProdbContext> dbContextProvider)
            : base(dbContextProvider)
        {
        }
        //add your common methods for all repositories
    }
    /// <summary>
    /// Base class for custom repositories of the application.
    /// This is a shortcut of <see cref="EA_ProdbRepositoryBase{TEntity,TPrimaryKey}"/> for <see cref="int"/> primary key.
    /// </summary>
    /// <typeparam name="TEntity">Entity type</typeparam>
    public abstract class EA_ProdbRepositoryBase<TEntity> : EA_ProdbRepositoryBase<TEntity, int>
        where TEntity : class, IEntity<int>
    {
        protected EA_ProdbRepositoryBase(IDbContextProvider<EA_ProdbContext> dbContextProvider)
            : base(dbContextProvider)
        {
        }
        //do not add any method here, add to the class above (since this inherits it)!!!
    }
    
    

    logs

    INFO  2025-09-28 23:04:54,393 [13   ] c.Infrastructure.ControllerActionInvoker - Route matched with {area = "app", action = "GetAll", controller = "TestEA"}. Executing controller action with signature System.Threading.Tasks.Task`1[System.Linq.IQueryable`1[Portail_GTC.Test.entities.ControleEA]] GetAllAsync() on controller Portail_GTC.EA.TestEAAppService (Portail_GTC.Application).
    WARN  2025-09-28 23:04:54,418 [13   ] oft.EntityFrameworkCore.Model.Validation - No store type was specified for the decimal property 'Id' on entity type 'ControleEA'. This will cause values to be silently truncated if they do not fit in the default precision and scale. Explicitly specify the SQL server column type that can accommodate all the values in 'OnModelCreating' using 'HasColumnType', specify precision and scale using 'HasPrecision', or configure a value converter using 'HasConversion'.
    WARN  2025-09-28 23:04:54,419 [13   ] oft.EntityFrameworkCore.Model.Validation - The decimal property 'Id' is part of a key on entity type 'ControleEA'. If the configured precision and scale don't match the column type in the database, this will cause values to be silently truncated if they do not fit in the default precision and scale. Consider using a different property as the key, or make sure that the database column type matches the model configuration and enable decimal rounding warnings using 'SET NUMERIC_ROUNDABORT ON'.
    WARN  2025-09-28 23:04:54,419 [13   ] oft.EntityFrameworkCore.Model.Validation - No store type was specified for the decimal property 'IdOrdreMission' on entity type 'ControleEA'. This will cause values to be silently truncated if they do not fit in the default precision and scale. Explicitly specify the SQL server column type that can accommodate all the values in 'OnModelCreating' using 'HasColumnType', specify precision and scale using 'HasPrecision', or configure a value converter using 'HasConversion'.
    ERROR 2025-09-28 23:04:54,570 [14   ] oft.EntityFrameworkCore.Database.Command - Failed executing DbCommand (114ms) [Parameters=[@Exploitant='?' (DbType = Int32), @Constructeur='?' (DbType = Int32), @NumLot='?', @NumExploitant='?', @NumConstructeur='?', @Nomclient='?', @CP='?', @Prestataire='?' (DbType = Int32), @Debut='?' (DbType = DateTime), @Fin='?' (DbType = DateTime), @Classe='?', @Approuve='?' (DbType = Int32), @DateAllSearch='?' (DbType = Int32)], CommandType='Text', CommandTimeout='30']
    EXEC wb_ControlesRT02 @Exploitant, @Constructeur, @NumLot, @NumExploitant, @NumConstructeur, @Nomclient, @CP, @Prestataire, @Debut, @Fin, @Classe, @Approuve, @DateAllSearch
    ERROR 2025-09-28 23:04:54,675 [14   ] Microsoft.EntityFrameworkCore.Query      - An exception occurred while iterating over the results of a query for context type 'Portail_GTC.EntityFrameworkCore.EA_ProdbContext'.
    Microsoft.Data.SqlClient.SqlException (0x80131904): Could not find stored procedure 'wb_ControlesRT02'.
       at Microsoft.Data.SqlClient.SqlCommand.<>c.<ExecuteDbDataReaderAsync>b__211_0(Task`1 result)
       at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
    --- End of stack trace from previous location ---
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
    --- End of stack trace from previous location ---
       at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Query.Internal.FromSqlQueryingEnumerable`1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Query.Internal.FromSqlQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
    ClientConnectionId:09122a63-29dd-48c8-9b4e-8d81585e7b08
    Error Number:2812,State:62,Class:16
    Microsoft.Data.SqlClient.SqlException (0x80131904): Could not find stored procedure 'wb_ControlesRT02'.
       at Microsoft.Data.SqlClient.SqlCommand.<>c.<ExecuteDbDataReaderAsync>b__211_0(Task`1 result)
       at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
    --- End of stack trace from previous location ---
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
    --- End of stack trace from previous location ---
       at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Query.Internal.FromSqlQueryingEnumerable`1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Query.Internal.FromSqlQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
    ClientConnectionId:09122a63-29dd-48c8-9b4e-8d81585e7b08
    Error Number:2812,State:62,Class:16
    ERROR 2025-09-28 23:05:24,442 [12   ] Mvc.ExceptionHandling.AbpExceptionFilter - Could not find stored procedure 'wb_ControlesRT02'.
    Microsoft.Data.SqlClient.SqlException (0x80131904): Could not find stored procedure 'wb_ControlesRT02'.
       at Microsoft.Data.SqlClient.SqlCommand.<>c.<ExecuteDbDataReaderAsync>b__211_0(Task`1 result)
       at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
    --- End of stack trace from previous location ---
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
    --- End of stack trace from previous location ---
       at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Query.Internal.FromSqlQueryingEnumerable`1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Query.Internal.FromSqlQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
       at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
       at Portail_GTC.repository.ControleEARepository.GetControlesAsync() in C:\source\Portail_GTC\Portail_GTC\aspnet-core\src\Portail_GTC.EntityFrameworkCore\repository\ControleEARepository.cs:line 56
       at Portail_GTC.EA.TestEAAppService.GetAllAsync() in C:\source\Portail_GTC\Portail_GTC\aspnet-core\src\Portail_GTC.Application\Test\TestEAAppService.cs:line 29
       at lambda_method2403(Closure, Object)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.&lt;InvokeNextActionFilterAsync&gt;g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.&lt;InvokeInnerFilterAsync&gt;g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.&lt;InvokeNextExceptionFilterAsync&gt;g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
    ClientConnectionId:09122a63-29dd-48c8-9b4e-8d81585e7b08
    Error Number:2812,State:62,Class:16
    INFO  2025-09-28 23:05:24,478 [12   ] .Mvc.Infrastructure.ObjectResultExecutor - Executing ObjectResult, writing value of type 'Abp.Web.Models.AjaxResponse'.
    INFO  2025-09-28 23:05:24,482 [12   ] c.Infrastructure.ControllerActionInvoker - Executed action Portail_GTC.EA.TestEAAppService.GetAllAsync (Portail_GTC.Application) in 30089.0646ms
    INFO  2025-09-28 23:05:24,483 [12   ] ft.AspNetCore.Routing.EndpointMiddleware - Executed endpoint 'Portail_GTC.EA.TestEAAppService.GetAllAsync (Portail_GTC.Application)'
    INFO  2025-09-28 23:05:24,483 [12   ] Microsoft.AspNetCore.Hosting.Diagnostics - Request finished HTTP/2 GET https://localhost:44301/api/services/app/TestEA/GetAll - 500 - application/json;+charset=utf-8 30095.1197ms
    
    
    
    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    oguzhanagir created
    Support Team

    Hi @gtc

    To resolve this, the following points should be checked

    EA_ProdbContext must use the connection string for the secondary database. Example configuration:

    public static class EA_ProdbContextConfigurer
    {
        public static void Configure(DbContextOptionsBuilder<EA_ProdbContext> builder, string connectionString)
        {
            builder.UseSqlServer(connectionString);
        }
    
        public static void Configure(DbContextOptionsBuilder<EA_ProdbContext> builder, DbConnection connection)
        {
            builder.UseSqlServer(connection);
        }
    }
    

    In appsettings.json, a dedicated entry should be added

    "ConnectionStrings": {
      "Default": "Server=.;Database=MainDb;Trusted_Connection=True;",
      "EA_Prod": "Server=.;Database=EA_ProdDb;Trusted_Connection=True;"
    }
    

    Inside Portail_GTCEntityFrameworkCoreModule, the second DbContext should be registered explicitly with its own connection string:

    public override void PreInitialize()
    {
        Configuration.Modules.AbpEfCore().AddDbContext<EA_ProdbContext>(options =>
        {
            if (options.ExistingConnection != null)
            {
                EA_ProdbContextConfigurer.Configure(options.DbContextOptions, options.ExistingConnection);
            }
            else
            {
                var connectionString = Configuration.GetConnectionString("EA_Prod");
                EA_ProdbContextConfigurer.Configure(options.DbContextOptions, connectionString);
            }
        });
    }
    

    When executing the stored procedure, the code should resolve EA_ProdbContext, not the default one:

    var context = await _dbContextProvider.GetDbContextAsync();
    var result = await context.ControleEAs
        .FromSqlRaw("EXEC wb_ControlesRT02 @Exploitant, @Constructeur, ...", parameters)
        .ToListAsync();
    

    If the procedure is created under a schema other than dbo (e.g., ea), EF Core will fail unless the schema name is included in the call:

    .FromSqlRaw("EXEC ea.wb_ControlesRT02 @Exploitant, @Constructeur, ...", parameters)
    
    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    gtc created

    Hello, thank you for your feedback. The GetconnectionString is not recognized in the configuration

    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)
  • User Avatar
    0
    oguzhanagir created
    Support Team

    Hi @gtc

    With the help of AppConfigurations, you can configure the second database connections string specified in appsettings.json as in the example below.

    Configuration.Modules.AbpEfCore().AddDbContext<EA_ProdbContext>(options =>
    {
        if (options.ExistingConnection != null)
        {
            EA_ProdbContextConfigurer.Configure(options.DbContextOptions, options.ExistingConnection);
        }
        else
        {
            var appConfiguration = AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder());
            var connectionString = appConfiguration.GetConnectionString("EA_Prod");
            
            EA_ProdbContextConfigurer.Configure(options.DbContextOptions, connectionString);
        }
    });
    
    Markdown is supported
    Copy & paste or drag & drop images (max 30 MB per image)