Desvendando o Entity Framework - A classe EntityConnection
Um dos benefícios de utilizar o Entity Framework é que ele remove a necessidade de escrever código para configurar a conexão com o banco de dados.
A partir do momento que uma string de conexão esta disponível para o Entity Framework, geralmente como parte do Entity ConnectionString, que é salva na seção ConnectionStrings, definida no arquivo configuração (web.config ou app.config), o Entity Framework irá automaticamente definir, abrir e fechar a conexão com o banco de dados para você.
Comparado com o código ADO .NET tradicional, onde você precisa instanciar, definir, e em muitos casos, explicitamente abrir uma conexão, instanciar e definir um comando, executar o comando e então explicitamente fechar a conexão, o Entity Framework, através do ObjectContext, cuida de todas essas tarefas para você em segundo plano.
Esta é uma vantagem que você terá em um cenário de consultas padrão, mas às vezes você vai querer ter um controle mais efetivo sobre como e quando as conexões estão sendo gerenciadas. Para estar apto a ter este controle vamos dar uma olhada em como o EntityConnection e o DbConnection se relacionam entre si; vamos ver também como forçar via código que eles trabalhem da maneira que você deseja quando o comportamento padrão não resolver o seu problema.
Nota: A classe EntityConnection contém uma referência ao Entity Data Model (EDM) e uma conexão com a fonte de dados; a classe DbConnection, do namespace System.Data.Common, representa uma conexão com um banco de dados.
EntityConnection versus Conexões de banco de dados
Uma EntityConnection não é uma conexão com um banco de dados. Embora você possa abrir e fechar uma EntityConnection, isso não significa que você esta abrindo e fechando uma conexão com um banco de dados. Se você usar o EntityClient diretamente ou deixar que os Object Services executem os seus comandos e consultas, a EntityConnection será apenas um caminho para a conexão com o banco de dados.
Nota: O provedor EntityClient usa os recursos de armazenamento específico das classes do ADO .NET Data Provider e o mapeamento para interagir com um modelo de entidades de dados e traduzir as operações realizadas no modelo conceitual em operações realizadas na fonte de dados física.
Uma EntityConnection é composto por 4 partes:
Você pode definir a EntityConnection declarativamente no arquivo de configuração (app.config ou web.config) . Abaixo temos um exemplo onde o nome da string de conexão e da string EntityConnection são definidos em um arquivo app.config:
<connectionStrings> <add name="MacorattiEntities" connectionString="metadata=res://*/MACModel.csdl|res://*/MACModel.ssdl|res://*/MACModel.msl; provider=System.Data.SqlClient; provider connection string='Data Source=.\SQLEXPRESS;Initial Catalog=Macoratti;Integrated Security=True; MultipleActiveResultSets=True'" providerName="System.Data.EntityClient" /> </connectionStrings> |
Nota: Quando o assistente de configuração do Entity Framework cria esta string para você , ele substitui as aspas em torno da provider connection string com um caractere ", o qual é o enconding XML para aspas. No exemplo acima estamos usando a notação com aspas para facilitar a legibilidade.
Por padrão o ObjectContext irá usar a string de conexão a partir do arquivo de configuração que coincide o nome definido no EntityContainer do seu modelo.
Nota: Um EntityContainter, definido no CSDL, representa um container de entidade no EDM e pode se consideradoc como um agrupamento lógico de conjuntos de entidades e associações. Ele controla o escopo das entidades e associações no modelo de objetos definido.
A string de conexão do banco de dados que esta embutida na string EntityConnection é passada adiante para o provedor do banco de dados que eventualmente realiza a conexão com o banco de dados.
Construindo strings EntityConnection
A EntityConnection é uma classe que fica no namespace EntityClient; veremos a seguir como construir strings EntityConnection usando o nome da string de conexão no arquivo de configuração que será passado como um parâmetro no construtor EntityConnection; neste caso a conexão será criada a partir dos detalhes fornecidos pela string de conexão:
Using conn As EntityConnection= New EntityConnection("name=MacorattiEntities")
Você também pode usar o método anterior para selecionar de forma explícita uma string de conexão particular a partir do arquivo de configuração quando instanciar um ObjectContext:
Dim context= New
MacorattiEntities("name=OutraConnectionString")
Quando você usa este construtor para um
EntityConnection ou ObjectContext , a
ConnectionString não é lida na sua totalidade. Para ler a string de conexão
completa a partir do arquivo de configuração você pode usar um dos métodos de
leitura de dados a partir do arquivo de configuração como
System.Configuration.ConfigurationManager.
Usando a classe EntityConnectionStringBuilder
Você pode também programar via código uma EntityConnectionString usando a classe EntityConnectionStringBuilder, a qual herda a partir de DbConnectionStringBuilder. Assim, você pode armazenar a localização dos seus arquivos metadata (.csdl. .msl, ssdl) em um arquivo de recurso e alterar via código o EntityConnectionString para apontar para esta localização. Você pode também querer alterar via código o provedor ADO .NET em tempo de execução.
No código exemplo a seguir lemos a string de conexão a partir do arquivo de configuração em uma string, em seguida criamos um EntityConnectionStringBuilder a partir daquela string, modificamos a propriedade Metadata e então instanciamos um ObjectContext com a nova EntityConnectionString
Dim connstring = ConfigurationManager.ConnectionStrings.Item"MacorattiEntities").ConnectionString Dim estringnew = New EntityConnectionStringBuilder(connstring) With estringnew .Metadata = My.Settings.MetadataFilePath Dim context = New MacorattiEntities(estringnew.ToString) Dim query = From con In context.Contacts Where _ con.Addresses.Any(Function(a) a.City = "Brasilia") End With |
var connstring =
ConfigurationManager.ConnectionStrings["MacorattiEntities"].ConnectionString; var estringnew = new EntityConnectionStringBuilder(connstring); estringnew.Metadata = Properties.Settings.Default.MetadataFilePath; var context = new MacorattiEntities(estringnew.ToString()); var query = from con in context.Contacts where con.Addresses.Any((a) => a.City == "Brasilia") select con; |
Como o parâmetro Metadata é uma string, não existe uma maneira fortemente tipada de criá-la.
Abrindo e fechando conexões com Entidades e Banco de dados
O método Open da EntityConnection (EntityConnection.Open) carrega os arquivos de metadata (lidos do modelo) se eles não tiveram ainda sido carregados na memória da aplicação. O método Open da EntityConnection chama o método Connection.Open do provedor do banco de dados. Da mesma forma o método Close da EntityConnection irá chamar o método Close da Connection do banco de dados.
Quando um ObjectContext executa uma consulta internamente ela cria uma EntityConnection e um EntityCommand executa o comando; tão logo os dados foram usados, se você chamar um método como ToList para ler todos os dados de uma vez ou se você iterar através dos dados até o fim, o contexto irá fechar a EntityConnection a qual irá por sua vez fechar a conexão com o banco de dados.
E como fica o tratamento do pool de conexões ?
Esta é uma pergunta recorrente, mas como o pool de conexões é controlado pelo provedor do banco de dados, a Entity Framework não interage de forma explicita em como o pool de conexões trabalha.
Desta forma apresentamos alguns conceitos básicos sobre o EntityConnection do EntityFramework.
Aguarde mais artigos da série Desvendando o EntityFramework.
Eu sei é apenas .NET, mas eu gosto...
Referências:
.NET - Introdução ao ADO .NET Entity Framework - Usando o EF em uma aplicação web
José Carlos Macoratti