Há algum tempo eu vinha tendo um problema com a utilização de coleções Lazy Load nas propriedades de algumas classes, através do meu framework.
É bom que se fale logo no início que esse framework (no seu módulo de persistência) é baseado no padrão Repository, utilizando, entre outros métodos, o ActiveRecord, do Castle Project, para modelar as classes e acessar o banco (rodando Linq nas consultas).
Pois bem, dado isto, um problema que encontrei diversas vezes foi na hora de chamar uma propriedade que é uma coleção e estava setado como Lazy=true no atributo “HasMany”.
Ocorria o seguinte erro:
Initializing[ClasseModelada#1]-failed to lazily initialize a collection of role: PropriedadeDeLista, no session or session was closed
Ou seja, o servidor indicava que não conseguia acessar os dados da coleção lazy por falta de uma sessão do ActiveRecord com o banco.
Durante muito tempo eu usei uma solução bem simples, de apenas 1 linha de código, e que funciona perfeitamente, mas que era chata, pois quando a esquecia, lá vinha o erro novamente:
using(new SessionScope())
{
... // código que acessa a propriedade Lazy
}
Para resolver esse “pequeno” problema, temos duas soluções possíveis:
A primeira, mais complicada, é inserindo no arquivo Global.asax.cs o seguinte código:
protected void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Items.Add("ar.sessionscope", new Castle.ActiveRecord.SessionScope());
}
protected void Application_EndRequest(object sender, EventArgs e)
{
try
{
Castle.ActiveRecord.SessionScope scope = HttpContext.Current.Items["ar.sessionscope"] as Castle.ActiveRecord.SessionScope;
if (scope != null)
scope.Dispose();
}
catch (Exception ex)
{
HttpContext.Current.Trace.Warn("Error", "EndRequest: " + ex.Message, ex);
}
}
Ou seja, a cada requisição da aplicação, é adicionado no contexto atual um SessionScope novo. Ao final da requisição, esse SessionScope é destruído.
Uma alternativa (melhor, na minha opinião) é a 2ª abordagem:
Apague todo o código acima e, no arquivo Web.config, insira o seguinte código:
<system.web>
<httpModules>
<add name="ar.sessionscope" type="Castle.ActiveRecord.Framework.SessionScopeWebModule, Castle.ActiveRecord"/>
</httpModules>
</system.web>
Pronto! O gerenciador dos módulos Http fará a manipulação do SessionScope automaticamente para a aplicação.
Todas as opções são eficientes, porém a 1ª abordagem perde um pouco em desempenho, pois, provavelmente, você não acessa o banco em 100% das requisições da sua aplicação. É necessário verificar se o mesmo ocorre com a 2ª opção. Mas esta análise de desempenho eu deixo pra você colocar nos comentários.
Até a próxima!
| Ofertas Relacionadas | ![]() Sony Ericsson Xperia Mini Pro Sk17 3g Wi Fi Android Hd Gps Mais info» R$ 535.00 até 18x de 40.13 | ![]() Celular Hiphone 4 Mp30 2 Chips Wi Fi Tv Fm Java Msn Touch 4g Mais info» R$ 119.00 até 18x de 8.93 | ![]() Smartphone Samsung Galaxy Ace S5830 800mhz 3g Wi Fi Gps Mais info» R$ 610.00 até 18x de 45.75 |
|---|
Tags: ActiveRecord, C#, sessão





