Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Erro de mais de um datareader aberto

Fiz o que foi sugerido na aula 5 atividade 8, mas quando tentei exibir o nome do artista da música, obtive um erro :

Unhandled exception. System.InvalidOperationException: There is already an open DataReader associated with this Connection which must be closed first.

Acredito que deve ser por ter um artistaDAL em uso.

Como faço para resolver isso?

Segue o código abaixo:

internal class MenuMostrarPorAnoLancamento : Menu
{
   public override void Executar(DAL<Artista> artistaDAL) {
        base.Executar(artistaDAL);
        ExibirTituloDaOpcao("Mostrar musicas por ano de lançamento");
        Console.Write("Digite o ano para consultar músicas:");
        string anoLancamento = Console.ReadLine()!;
        var musicaDal = new DAL<Musica>(new ScreenSoundContext());
        var listaAnoLancamento = musicaDal.RecuperarListaPor(a => a.AnoLancamento == Convert.ToInt32(anoLancamento));
        if (listaAnoLancamento.Any())
        {
            Console.WriteLine($"\nMusicas do Ano {anoLancamento}:");
            foreach (var musica in listaAnoLancamento)
            {
                //musica.ExibirFichaTecnica();
                Console.WriteLine($"Musica: {musica.Nome}, Artista: {musica.Artista?.Nome}");
            }
            Console.WriteLine("\nDigite uma tecla para voltar ao menu principal");
            Console.ReadKey();
            Console.Clear();
        }
        else
        {
            Console.WriteLine($"\nO ano {anoLancamento} não foi encontrada!");
            Console.WriteLine("Digite uma tecla para voltar ao menu principal");
            Console.ReadKey();
            Console.Clear();
        }
   }
}

Obrigado.

2 respostas
solução!

Oi, Angelo, tudo bem?

O problema acontece, pois quando você tenta acessar a propriedade musica.Artista.Nome, o EF tenta abrir uma nova consulta ao banco para buscar o nome do artista, mas a consulta anterior (que busca as músicas) continua aberta, causando o erro.

Uma maneira de resolver isso é forçar o EF a executar a consulta imediatamente, carregando todos os dados necessários de uma vez. Isso pode ser feito com o método ToList(), por exemplo. Veja como ficaria o seu código:

var listaAnoLancamento = musicaDal.RecuperarListaPor(a => a.AnoLancamento == Convert.ToInt32(anoLancamento)).ToList();

Outra solução seria habilitar o MARS (Multiple Active Result Sets), que permite mais de um DataReader aberto na mesma conexão. Isso pode ser feito adicionando MultipleActiveResultSets=True na sua string de conexão. No entanto, essa opção pode ter implicações de desempenho, então eu recomendaria tentar a primeira solução primeiro.

Espero ter ajudado. Caso tenha dúvidas, conte com o fórum. Abraços!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓. Bons Estudos!

Resposta certeira, obrigado Rodrigo!