I'm facing a really strange issue with Dapper.SqlMapper.QueryAsync:
Query:
_dbSession.OpenCon();
var query = $@"
SELECT
at.*, dpt.*, c.*, cnt.*, mEnc.*, atUsr.*, usr.*
FROM Atendimento AS at
INNER JOIN Departamento AS dpt ON at.DepartamentoId = dpt.Id
INNER JOIN Canal AS c ON at.CanalId = c.Id
LEFT JOIN Contato AS cnt ON at.ContatoId = cnt.Id
LEFT JOIN MotivoEncerramento as mEnc ON at.MotivoEncerramentoId = mEnc.id
LEFT JOIN (
AtendimentoUsuario AS atUsr
INNER JOIN Users AS usr ON atUsr.UserId = usr.Id
) ON at.Id = atUsr.AtendimentoId
WHERE at.IdRef = '{idRef}'
ORDER BY dpt.Id, c.Id, atUsr.Id, usr.Id;";
var atendimentos = await Dapper.SqlMapper.QueryAsync<Atendimento, Departamento, Canal, Contato, MotivoEncerramento, AtendimentoUsuario, Usuario, Atendimento>(
_dbSession.Connection,
query,
(atendimento, departamento, canal, contato, motivoEncerramento, atUsuario, usuario) =>
{
atendimento.Departamento = departamento;
atendimento.Contato = contato;
atendimento.MotivoEncerramento = motivoEncerramento;
atendimento.Canal = canal;
atendimento.AtendimentoUsuarios = new List<AtendimentoUsuario>();
if (atUsuario is not null)
{
atUsuario.Usuario = usuario;
atendimento.AtendimentoUsuarios.Add(atUsuario);
}
return atendimento;
});
var result = atendimentos.GroupBy(a => a.Id).Select(g =>
{
var groupedAtendimento = g.First();
if (g.Any(c => c.AtendimentoUsuarios.Count > 0))
{
groupedAtendimento.AtendimentoUsuarios = g.Select(a => a.AtendimentoUsuarios.SingleOrDefault()).ToList();
}
return groupedAtendimento;
});
atendimento = result.First();
_dbSession.Dispose();
Most times it is running fine but sometimes it returns Object reference not set to an instance of an object with this StackTrace:
at MySqlConnector.MySqlDataReader.ActivateResultSet(CancellationToken cancellationToken) in //src/MySqlConnector/MySqlDataReader.cs:line 108 -|-
at MySqlConnector.MySqlDataReader.CreateAsync(CommandListPosition commandListPosition, ICommandPayloadCreator payloadCreator, IDictionary2 cachedProcedures, IMySqlCommand command, CommandBehavior behavior, Activity activity, IOBehavior ioBehavior, CancellationToken cancellationToken) in /_/src/MySqlConnector/MySqlDataReader.cs:line 456 -|- at MySqlConnector.Core.CommandExecutor.ExecuteReaderAsync(IReadOnlyList1 commands, ICommandPayloadCreator payloadCreator, CommandBehavior behavior, Activity activity, IOBehavior ioBehavior, CancellationToken cancellationToken) in //src/MySqlConnector/Core/CommandExecutor.cs:line 56 -|- at MySqlConnector.MySqlCommand.ExecuteReaderAsync(CommandBehavior behavior, IOBehavior ioBehavior, CancellationToken cancellationToken) in //src/MySqlConnector/MySqlCommand.cs:line 331 -|-
at MySqlConnector.MySqlCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken) in //src/MySqlConnector/MySqlCommand.cs:line 323 -|-
at Datadog.Trace.ClrProfiler.CallTarget.Handlers.Continuations.TaskContinuationGenerator4.SyncCallbackHandler.ContinuationAction(Task1 previousTask, TTarget target, CallTargetState state) in /project/tracer/src/Datadog.Trace/ClrProfiler/CallTarget/Handlers/Continuations/TaskContinuationGenerator`1.cs:line 143 -|-
at Dapper.SqlMapper.MultiMapAsync[TFirst,TSecond,TThird,TFourth,TFifth,TSixth,TSeventh,TReturn](IDbConnection cnn, CommandDefinition command, Delegate map, String splitOn) in /_/Dapper/SqlMapper.Async.cs:line 921 -|-
at Comzada.Infra.Data.Repository.CustomersRepository.GetByIdRefAsync(String idRef, Boolean forceCacheUpdate) in /home/centos/compile_server/Comzada.Infra.Data/Repository/CustomersRepository.cs:line 263
The strange thing is that it is intermittent and hard to figure out. I thought that it could be something with the connection but I always open/dispose it.
Any help will be very appreciated.
ConnectionString:
Server=******;DataBase=******;Uid=****;Pwd=*****5;default command timeout=0;SslMode=none;max pool size=2000;Connect Timeout=300;convert zero datetime=True;ConnectionIdleTimeout=5;Pooling=true;MinimumPoolSize=25
DbSession added to Startup.cs:
services.AddScoped<DbSession>();
DbSession.cs:
using System;
using System.Data;
using Microsoft.Extensions.Configuration;
using MySqlConnector;
using static Dapper.SqlMapper;
namespace ***.Infra.Data.Context
{
public sealed class DbSession : IDisposable
{
public IDbConnection Connection;
private readonly IConfiguration _configuration;
public DbSession(IConfiguration configuration)
{
_configuration = configuration;
}
public void OpenCon(bool masterInstance = false)
{
var conStr = masterInstance ? "MySqlConnectionString" : "MySqlConnectionStringRead";
Connection = new MySqlConnection(_configuration.GetValue<string>($"ConnectionStrings:{conStr}"));
Connection.Open();
}
public void Dispose() => Connection?.Dispose();
}
}