views:

65

answers:

3

Hi,

I am using ASP.NET MVC2 with NHibernate, but am facing an issue. All calls to the database via NHibernate should be inside a transaction, however code inside the view kicks off database calls in some instances. Thus there is a need to be able to commit the transaction after the view has rendered.

For example displaying a list of users and their user roles you might show the user role using this code: <%: Model.UserRole.Name %>

This will cause a hit on the database as the UserRole is loaded using a NHibernate proxy.

You can fetch the UserRole eagerly which circumvents the issue in this case, but there are cases where it is much faster to use lazy loading.

Anyway, is there a way to run code after the view has rendered?

A: 

You could use

try 
{
    return View();
}
finally 
{
    // do stuff after the view was rendered
}

But I am not sure as to what the problem exactly is and what are you trying to achieve. If you want an Action to run inside of a transaction (which you should), just put [Transaction] on top of the Action method.

[Transaction]
public ActionResult SomeAction() { }
HeavyWave
The try finally doesn't work.Which transaction attribute are you referring to? I tried this one: http://weblogs.asp.net/srkirkland/archive/2009/09/03/asp-net-mvc-transaction-attribute-using-nhibernate.aspxbut it also doesn't catch any requests made in the view
Alistair
Finally should always be executed. What do you mean by "doesn't work"?Sorry, I was referring to http://www.sharparchitecture.net/ TransactionAttribute.
HeavyWave
As in the finally is executed before the view is rendered.
Alistair
+3  A: 

Have you tried to use session-per-request pattern? It's a very natural way of handling NHibernate sessions in web environment.

There are many information available when you do a Google search on "NHibernate session per request", like this blog post.

Also, take a look at great Bill McCafferty's article NHibernate Best Practices. Although it's written for NHibernate 1.2, it has a wealth of information. While there, his S#arp Architecture also looks very cool :)

Miroslav Popovic
Thanks, you also included what I need in your links.
Alistair
A: 

How about an action filter?

public class CleanUpAttribute: ActionFilterAttribute
{
    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        //cleanup code here
    }
}

Then you decorate your controllers with this attribute.

uvita
Perfect, Thanks. I modified http://weblogs.asp.net/srkirkland/archive/2009/09/03/asp-net-mvc-transaction-attribute-using-nhibernate.aspx to work this way.
Alistair
Nothing to see here..
Alistair