Entity Framework Power Tools CTP1

5/18/2011 11:56:00 PM By Felipe Pessoto

O time do Entity Framework/ADO.NET acabou de lançar uma ferramenta sensional, o Entity Framework Power Tools CTP1.

Quem usa Code First sempre tem que ter um trabalhão pra mapear um banco de dados já existente, principalmente se for muito grande e com falhas de modelagem. Com essa nova ferramenta, quando você clica com o botão direito em um projeto C#, tem uma nova opção: "Entity Framework -> Reverse Engineer Code First"

Read more...

EF Feature CTP5

12/8/2010 12:51:00 AM By Felipe Pessoto

Com alguns dias de atraso, foi lançado o quinto e último CTP do Entity Framework Code First. A versão final é esperada para o final do primeiro trimestre de 2011. É importante resaltar os known issues:

  • Table & Column Mapping in the Fluent API
    We have done some work to make the mapping of classes/properties to tables/columns simpler and more intuitive in CTP5. We are still working to improve the quality of this new work, particularly around the mapping of inheritance hierarchies.
  • Pluggable Conventions 
    CTP5 includes a very early preview of this feature that is not complete and has not been extensively tested.
  • The new Validation feature is currently only supported when using Code First  


As novidades são:

  Read more...

Acesso à Banco de Dados III Usando Parâmetros

1/15/2008 2:32:00 PM By Felipe Pessoto

Agora que já sabemos como executar comando no banco de dados, vamos aprender à executá-los usando parâmetros.

Os parâmetros são como variáveis que contém valores que são enviados e retornados do banco de dados, eles têm tipo e um conteúdo assim como as variáveis que usamos nos nossos programas.

Para definirmos o tipo do parâmetro usamos o enum SqlDbType que têm os tipos usados no SQL Server(para o Oracle temos o OracleType). Tudo isso será melhor abordado adiante, faremos um exemplo prático.

Geralmente usamos parâmetros quando queremos mudar algo rapidamente e especificamente, na maioria das vezes na cláusula WHERE. Outra vantagem é a segurança proporcionada, pois ao deixar de fazer concatenação de strings para formar uma Query SQL eliminamos o risco de um SQL Injection. A seguir um exemplo de uma Query usando parâmetro:

SELECT nome, idade, cidade FROM Clientes WHERE cd_cliente= @Codigos

Os parâmetros podem ser de entrada, saída ou entrada e saída, definido na propriedade Direction. Por padrão o parâmetro é definido como de entrada.

Para criarmos um parâmetro declaramos uma instância da classe Parameter, e atribuímos o seu nome e tipo de dado, que deve coincidir com o esperado pela fonte de dados, exemplo:

SqlParameter MeuParametro = new SqlParameter();
MeuParametro.ParameterName = "@Codigo";
MeuParametro.SqlDbType = SqlDbType.Int;

//Exemplo definindo como parâmetro de saída
MeuParametro.Direction.ParameterDirection.Output;

Depois que temos nosso parâmetro, vamos adicionar ele ao objeto Command. Os objetos Command tem uma propriedade chamada Parameters, que representa uma coleção de parâmetros. Então usamos o método Add:

MeuComando.Parameters.Add(MeuParametro);

Falta apenas, é claro, definirmos o valor do nosso parâmetro(caso seja de entrada ou de entrada e saída):

MeuParametro.Value = 50;

A partir daí não muda mais nada, podemos executar o nosso comando como fizemos anteriormente:

SqlDataReader reader = MeuComando.ExecuteReader();

Acesso à Banco de Dados II Executando Comandos

1/10/2008 12:11:00 PM By Felipe Pessoto

Para se executar comando SQL ou Stored Procedures em um banco de dados, usamos objetos Command.

Assim como acontece com as conexões temos um objeto Command específico para cada Data Provider. Se você estiver usando um SqlConnection para se conectar ao SQL Server deve também usar SqlCommand para executar os comandos, se estiver usando um Provider OLE DB, o OleDbCommand será usado e assim por adiante.

As propriedades principais dos objetos Command são CommandText, CommandType e Connection.
O CommandType é para você especificar que tipo de comando será usado, se é uma Query SQL ou Stored Procedure. Exemplo:

SqlCommand.CommandType = CommandType.Text;
SqlCommand.CommandType = CommandType.StoredProcedure;

E então deve especificar na propriedade CommandText a Query SQL ou o nome da Stored Procedure.
A propriedade Connection é usada pra saber em qual conexão aquela instrução será executada. Você atribuir uma conexão previamente criada à essa propriedade. Exemplos:

 

SqlCommand MeuComando = new SqlCommand();
MeuComando.Connection = NorthwindConnection;
MeuComando.CommandType = CommandType.Text;
MeuComando.CommandText = "SELECT * FROM Customers";
 
SqlCommand TopTenCommand = new SqlCommand();
TopTenCommand.Connection = NorthwindConnection;
TopTenCommand.CommandType = CommandType.StoredProcedure;
TopTenCommand.CommandText = "Ten Most Expensive Products";

Depois que você tiver configurado seu objeto Command, deve executa-lo. Para isso temos 3 possibilidades, executar um comando que não retorna dados(ExecuteNonQuery), que retorna os dados linha por linha(ExecuteReader) ou que retorna apenas um valor(ExecuteScalar, primeira coluna da primeira linha). Exemplo de ExecuteScalar e ExecuteNonQuery:

 
SqlCommand ExecuteScalarCommand = new SqlCommand();
ExecuteScalarCommand.Connection = ObjetodeConexao;
ExecuteScalarCommand.CommandType = CommandType.Text;
ExecuteScalarCommand.CommandText = "SELECT Count(*) FROM Customers";

ExecuteScalarCommand.Connection.Open();
int CustomerCount = (int)ExecuteScalarCommand.ExecuteScalar();
ExecuteScalarCommand.Connection.Close();

SqlCommand CreateTableCommand = new SqlCommand();
CreateTableCommand.Connection = NorthwindConnection;
CreateTableCommand.CommandType = CommandType.Text;
CreateTableCommand.CommandText = "CREATE TABLE Clientes (" +
"[ClienteID] [int] IDENTITY(1,1) NOT NULL, " +
"[Nome] [nvarchar](50) NULL, )";

CreateTableCommand.ExecuteNonQuery();​
 

 

Para o ExecuteReader temos um pouco mais de trabalho. Criamos um objeto DataReader para ler a tabela retornada e executamos seu método Read(). Um ponteiro estará apontando para a primeira linha dessa tabela, e cada vez que executamos o Read() é retornado True se ouver mais linhas e o ponteiro é passado para a seguinte. Exemplo de ExecuteReader:

 

ExecuteSqlCommand.CommandText = "SELECT * FROM Customers;";
SqlDataReader reader = ExecuteSqlCommand.ExecuteReader();
 
StringBuilder results = new StringBuilder();
while (reader.Read())
{
for (int i = 0; i < reader.FieldCount; i++)
{
results.Append(reader[i].ToString() + "\t");
}
results.Append(Environment.NewLine);
}​

 

E aqui terminamos mais uma parte da série Acesso à Banco de Dados, aprendendo como obter resultados de um Banco de Dados

Acesso à Banco de Dados I Conexão

1/9/2008 7:39:00 PM By Felipe Pessoto

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.