Vou dar uma pausa na série Covariância e Contravariância pra falar um pouco sobre conceitos Básicos de Acesso a Banco de Dados.
Tem muita coisa que quero escrever, mas vai depender do meu tempo livre, e ainda tenho que terminar o livro do exame 70-526(já foram 5cap.)
Outro assunto muito interessanta é o LINQ, ele facilita muito o acesso ao banco de dados e dá mais confiança já que é tudo verificado em tempo de compilação. Mas isso fica pra uma próxima oportunidade.
Continuando, vamos estudar um pouco os objetos de conexão.
Primeiro, o que é um objeto de conexão?
O objeto de conexão é um "canal" que seus comandos e querys vão usar para se comunicar ao banco e dados. Ele também vai determinar se você vai usar Pool de Conexões(veremos posteriormente).
O Visual Studio permite que você gerencie suas conexões pela janela Server Explorer. As conexões adicionadas pelo Server Explorer ficam acessíveis à todos os projetos que você criar.
Para adicionar uma nova conexão é muito simples, abaixo mostro como adicionar um arquivo MDB do Access:
Quando você clicar em OK a nova conexão já será adicionada ao Server Explorer.
Pra adicionar uma conexão no SQL Server é só clicar no botão Change e escolher o Microsoft SQL Server. Alguns itens serão adicionados à janela, como a opção se usar autenticação integrada ou um usuário do SQL Server(explicarei adiante).
Outra forma de se criar uma conexão é via código. Nativamente o ADO.Net vem com objetos de conexão para SQL Server(SqlConnection), Oracle(OracleConnection), ODBC(OdbcConnection) e OLE DB(OleDbConnection).
Para usar estes objetos você vai precisar configurar a ConnectionString, indicando o DataSource, Database, Credenciais de Segurança, etc.
Exemplo:
SqlConnection ConnectionSql = new SqlConnection (@"Data Source=.\sqlexpress;Initial Catalog=Northwind;Integrated Security=True");
Neste exemplo conectamos à instância sqlexpress da máquina local, usando o banco de dados Northwind e segurança integrada.
Quando usamos Segurança Integrada, o usuário atual do Windows será usado. Este tipo de autenticação é a mais recomendada, então use-a sempre que possível.
Depois de criada, podemos abrir nossa conexão usando o método Open():
ConnectionSql.Open();
E para fecharmos usamos o método Close():
ConnectionSql.Close();
Sempre que uma conexão muda de estado(como abrir uma conexão fechada), você pode ser notificado usando o evento StateChange:
private void ConnectionSql_StateChange(object sender, StateChangeEventArgs e)
{
Label1.Text = e.CurrentState.ToString();
}
Outro evento interessante é o InfoMessage, ele é disparado quando algum aviso não crítico é recebido do banco de dados.
private void ConnectionSql_InfoMessage(object sender, SqlInfoMessageEventArgs e)
{
MessageBox.Show(e.Message);
}
Connection Pools
O Pool de Conexões tem um papel muito importante na questão da performance. Cada vez que é instanciado uma nova conexão é usado muito tempo de processamento, então faz sentido guardarmos as conexões por um tempo antes de destrui-las.
As conexões são reutilizadas quando estão no mesmo processo, application domain e string de conexão.
Podemos controlar o comportamento do Pool de Conexões através da string de conexão, vou listar os valores usados:
Connection Lifetime - Quando uma conexão é devolvida ao pool, é verificado à quantos segundos ela foi criada, se ultrapassar o valor definido aqui, a conexão é destruida.
Load Balance Timeout - O tempo mínimo que uma conexão fica na fila antes de ser destruída.
Max Pool Size - O número máximo de conexões que podem ficar na fila para cada string de conexão.
Min Pool Size - O número mínimo de conexões que devem ficar na fila.
Exemplo:
"Data Source=.\sqlexpress;Initial Catalog=Northwind;Integrated Security=True;Min Pool Size=10"
Caso você queira limpar a fila de uma determinada conexão pode usar o método ClearPool, e também é possível limpar o pool de todas as conexões de um determinado providor usando o método ClearAllPools.
Por padrão o Pool de Conexões já vem ativado, então você não precisa se preocupar em ativa-lo.
Manipulando Erros de Conexão
Para manipular um erro de conexão você usa o try/catch, capturando a exceção SqlException.
Essa classe contém uma coleção SqlErrorCollection na propriedade SqlException.Errors com pelo menos um objeto SqlError.
Exemplo:
try
{
connection.Open();
}
catch (SqlException ex)
{
string mensagem = "";
foreach (SqlError ConnectionError in ex.Errors)
{
mensagem += ConnectionError.Message + " (error: " + ConnectionError.Number.ToString() + ")" + Environment.NewLine;
if (ConnectionError.Number == 18452)
{
MessageBox.Show("Dados de Login Inválidos");
}
}
MessageBox.Show(mensagem);
}
Procurando SQL Servers disponíveis na rede
A classe SqlDataSourceEnumerator tem uma propriedade chamada Instance que pode ser usada para buscar por servidor SQL Server na rede. Basta executar o método GetDataSources() e será retornado um DataTable contendo informações sobre cada SQL Server encontrado.
Os servidores encontrados vão depender das configurações da rede, firewall, etc.
O DataTable retornado pelo GetDataSources() conterá as seguintes colunas:
ServerName - Nome do servidor
InstanceName - Nome da instância do SQL Server
IsClustered - Indica se o servidor é parte de um cluster
Version - Versao do SQL Server
Exemplo:
SqlDataSourceEnumerator instance = SqlDataSourceEnumerator.Instance;
MeuGrid.DataSource = instance.GetDataSources();
Aqui acabamos a parte sobre Conexões. Espero escrever a próxima parte em breve.
Até a próxima.