ADO .NET - Executando Múltiplos Comandos em uma única conexão
Se você usa o objeto DataReader em seus aplicativos e tentou utilizar mais de um comando em uma conexão aberta já deve ter visto a mensagem de erro : "There is already an open DataReader associated with this Command which must be closed first." ("Já existe um DataReader aberto associado a esta conexão que deve ser fechado...." )
Então não posso executar mais de um comando em uma mesma conexão ???
Pode, mas para isso você tem que ativar o recurso MARS - Multiple Active Result Sets.
O recurso MARS possibilita abrir múltiplos objetos SqlDataReader em uma única conexão. Ele permite que um aplicativo tenha mais de um SqlDataReader aberto em uma conexão quando cada instância do SqlDataReader é iniciada a partir de um comando separado. Cada objeto SqlCommand que você adicionar acrescenta uma sessão adicional para a conexão.
O recurso MARS está disponível em muitos SGBDs, sendo que o SQL Server 2005 foi o primeiro a dar suporte ao MARS. Você pode controlar explicitamente a ativação do recurso utilizando um par de palavras-chave em sua seqüência de conexão. Para ativar o recurso MARS em sua conexão você define explicitamente o atributo MultipleActiveResultSets na seqüência de conexão para True da seguinte forma:
string northwindConnectionString = "Server=localhost;Database=Northwind;Trusted_Connection=True;MultipleActiveResultSets=True";
Vou mostrar um exemplo prático usando os seguintes recursos:
Criando o projeto
Neste projeto exemplo vamos abrir dois DataReader usando dois comandos na mesma conexão:
Vamos criar um novo projeto no Visual C# 2010 Express Edition acionando o menu File -> New Project e a seguir escolhendo o template Windows Forms Application;
Informe o nome MultiplosComandos_PorConexao e clique no botão OK;
A seguir abra a janela Database Explorer e clique no ícone Data Connections com o botão direito do mouse e selecione Add Connections;
Na janela Add Connection escolha o Data Source - Microsoft SQL Server Database File (SqlClient) - e informe o local do banco de dados Northwind.mdf;
Obs: Eu estou anexando o banco de dados Northwind.mdf no meu SQL Server.
Após clicar no botão OK você deverá ter acesso a todos os objetos do banco de dados Northwind.mdf no SQL Server.
No formulário padrão form1.cs inclua os seguintes controles:
Disponha os controles conforme o leiaute da figura a seguir:
Vamos declarar os seguintes namespaces no inicio do formulário:
using
System;
using System.Windows.Forms;
using System.Data.SqlClient;
Vamos definir a string de conexão e ativar o recurso MARS :
string sqlConnectString = @"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\dados\Northwind.MDF;Integrated Security=True;Connect Timeout=30;User Instance=True;MultipleActiveResultSets=True";
O código do evento Click do botão Executar é mostrado a seguir:
private void btnExecutar_Click(object sender, EventArgs e) { string sqlConnectString = @"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\dados\Northwind.MDF;Integrated Security=True;Connect Timeout=30;User Instance=True;MultipleActiveResultSets=True"; SqlConnection connection = new SqlConnection(sqlConnectString); // cria o DataReader com 3 registros da tabela Orders SqlCommand cmdOrder = connection.CreateCommand(); cmdOrder.CommandText ="SELECT TOP 5 OrderID, OrderDate,ShipCity FROM Orders"; connection.Open(); SqlDataReader drOrder = cmdOrder.ExecuteReader(); // Percorre o reader com os registros dos pedidos while (drOrder.Read()) { lstDados.Items.Add("Pedido ID : " + drOrder["OrderID"] + " Cidade : " + drOrder["ShipCity"]); // Cria um DataReader com os detalhes do pedido SqlCommand cmdDetail = connection.CreateCommand(); cmdDetail.CommandText = "SELECT ProductID, Quantity FROM [Order Details] WHERE OrderID=" + drOrder["OrderID"]; // percorre os detalhes do pedido para o pedido using (SqlDataReader drDetail = cmdDetail.ExecuteReader()) { while (drDetail.Read()) { lstDados.Items.Add("\tProduto ID : " + drDetail["ProductID"] + "\tQuantidade : " + drDetail["Quantity"]); } lstDados.Items.Add("-------------------------------------------------------------------"); drDetail.Dispose(); } } connection.Close(); } } |
No código acima temos o seguinte:
Executando o projeto iremos obter o seguinte resultado:
O exemplo mostra que ativando o recurso MARS podemos usar mais de um comando em uma única conexão.
Pegue o projeto completo aqui: MultiplosComandos_PorConexao.zip
Mat 3:11
Eu (João Batista), na verdade, vos batizo em água, na base do arrependimento; mas aquele (Jesus) que vem após mim é mais poderoso do que eu, que nem sou digno de levar-lhe as alparcas; ele vos batizará no Espírito Santo, e em fogo.Mat 3:12
A sua pá ele tem na mão, e limpará bem a sua eira; recolherá o seu trigo ao celeiro, mas queimará a palha em fogo inextinguível.Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#