Entity Framework- Usando o Entity Framework em aplicações ASP .NET


Quando uma aplicação Web é executada, a ASP .NET mantém informação sobre a aplicação atual, sobre cada sessão do usuário, sobre a requisição HTTP atual, sobre a página requisitada e por ai vai...

Para fazer isso a ASP .NET contém diversas classes para encapsular a informação do contexto.

A ASP .NET faz instâncias dessas classes disponíveis como objetos intrínsecos que você pode acessar a partir do seu código. A seguir temos uma relação desses objetos intrínsecos e das classes que eles instanciam:

Nome do Objeto Classe ASP.NET
Response HttpResponse
Request HttpRequest
Context HttpContext
Server HttpServerUtility
Application HttpApplicationState
Session HttpSessionState
Trace TraceContext

Da mesma forma o ciclo de vida de uma página ASP .NET pode ser resumido conforme o esquema a seguir:

Tomando por base as informações do ciclo de vida de uma página ASP .NET, mesmo que você realizar todo o trabalho necessário usando o ObjectContext gerado pelo Entity Framework no code-behind da página, esse contexto, o qual é instanciado pela página, será destruído quando a página for liberada.

Dessa forma quaisquer entidades que forem criadas na página também serão destruídas da mesma forma. (Por este motivo as páginas web são por natureza sem estado.)

Na figura abaixo temos o ciclo de vida da página ASP .NET usando o ObjectContext criado pelo Entity Framework:

Concluímos que não podemos simplesmente instanciar um ObjectContext, efetuar as consultas para obter as entidades, realizar as operações e persistir as informações chamando o método SaveChanges() pois nunca retornaremos para o mesmo ObjectContext criado no início, e, portanto não teremos como gerenciar o estado dos objetos.

Este é justamente o grande desafio para trabalhar com o EntityFramework em aplicações ASP .NET.

Se sua aplicação precisa somente exibir dados e informações você pode retornar os dados de alguma forma para a página e usar código para preencher os controles ou efetuar a vinculação dos dados.

O problema é quando você realizar qualquer alteração nos objetos em sua aplicação web usando o Entity Framework.

Para contornar este problema você deve ter o cuidado de não retornar as consultas a partir do seu código, ao invés disso, você deve retornar o resultado dessas consultas, quer seja um simples objeto, uma coleção, uma Lista ou algo parecido.

Você não deve retornar um ObjectQuery ou uma consulta LINQ to Entities pois a execução da consulta requer um ObjectContext e se você retornar a consulta da sua classe de negócio ela será desanexada (detached) do contexto assim que objeto for liberado.

No código do exemplo abaixo o método da classe de negócio esta retornando um IQueryable do objetos Clientes:

public IQueryable<Customer> GetClientes(int cliID)
{
  return _ctx.Cliente.Where(c => c.ClienteID == cliID);
}

Em uma página ASP .NET você pode atribuir para a fonte de dados de um controle o resultado desta operação. Como você esta retornando um tipo IEnumerable isso será permitido. Dessa forma podemos fazer assim:

ListView1.DataSource=dal.GetCliente(570);

De outra forma a consulta não será executada até que a página inicia a renderização do controle ListView, e pode ser que o objeto de negócio não exista mais e a execução venha a falhar.

Portanto, retorne os resultados das consultas e não as consultas em suas classes de negócio.

Assim você não tem que se preocupar como os métodos que serão afetados pelo ciclo de vida da página, e, além disso ao executar a consulta e forçar o resultado usando um First, ToList, ou Execute, quando a iteração for concluída o EntityConnection e a conexão com o banco de dados será liberada e será outra preocupação que você não terá que ter. Matou dois coelhos com um golpe só...

Para tornar mais claro este enfoque vejamos um exemplo onde estamos retornando o resultado de uma consulta em um método da nossa classe de negócio:

Public Function GetCliente(ByVal ContatoID As Int32) As Cliente

Dim cli =  contexto.Contatos.OfType(Of Cliente) _
              .Include("Enderecos") _
              .Include("nome") _
              .Where("ct.Contatoid=" & ContatoID)

Dim cliente as Cliente = cli.FirstOrDefault()
'Aqui estamos retornando o objeto Cliente e não a consulta
Return cliente
End Function

A página ASP .NET pode então instanciar uma classe , chamar o método GetCliente e então preencher os controles usando os dados retornados, conforme o código a seguir:

Protected Sub Page_Load(ByVal sender As Object,ByVal e As System.EventArgs) Handles Me.Load

  If Not IsPostBack Then
    Dim dal = New SuaClasseDeNegocios()
    Dim cli = dal.GetCliente(_cliID)
    popularTextBoxes(cli)
    gridView_Enderecos.DataSource = cli.Enderecos
    gridView_Enderecos.DataBind()
  End If

End Sub

Como o comportamento padrão dos controles é salvar os valores a serem exibidos no View State, não será necessário retornar os dados da página a cada post back.

Dessa forma quando desejarmos apenas exibir o resultado as coisas são simples.

O problema é tratar as alterações dos objetos no ObjectContext mas isso será tratado em outro artigo...

Aguarde mais artigos sobre Entity Framework.

Eu sei é apenas Entity Framework, mas eu gosto.

Referências:


José Carlos Macoratti