我目前正在编写一个新的应用程序,尽管公司标准是使用NHibernate(因为这是所有项目都通用的标准),但我选择使用ASP.NET MVC 3,因为它现在已经非常成熟。我在控制器中实现了我的事务处理(这似乎是你应该这样做的方式),所以在我的根控制器中看起来像这样:
[TransactionPerRequest]
public class FbsController : Controller
{
}
然后,我所有的控制器都继承自
FbsController
。之所以这样做是因为我的90%操作都会访问数据库,所以为了剩下10%的操作去创建和处理事务(这些很少执行),不值得为每个操作添加[TransactionPerRequest]
标记。关于NHibernate sessions的问题一直困扰着我。在存储库类中,我有类似以下内容的代码,虽然在其他项目中可能不同:
public void Add(User user)
{
using (ISession session = NHibernateHelper.OpenSession())
{
session.Save(user);
}
}
public void Remove(User user)
{
using (ISession session = NHibernateHelper.OpenSession())
{
session.Delete(user);
}
}
public User GetById(int userId)
{
using (ISession session = NHibernateHelper.OpenSession())
{
return session.QueryOver<User>()
.Where(c => c.UserID == userId)
.SingleOrDefault();
}
}
因此,对于我存储库中的大多数函数,我必须打开会话。有没有办法避免这种行为,以便我不必在每个存储库方法内部打开会话?这似乎有点违反直觉,因为我通常必须为每个函数都执行此操作。我想知道其他人在处理散布在代码中的事务和会话问题时采用了什么解决方案。
实际上,我希望我的存储库方法看起来像以下内容:
public void Add(User user)
{
session.Save(user);
}
public void Remove(User user)
{
session.Delete(user);
}
public User GetById(int userId)
{
return session.QueryOver<User>()
.Where(c => c.UserID == userId)
.SingleOrDefault();
}
所有事情都隐式地处理。
HttpContext.Current.Items["NHibernateSession"]
,然后配置你的 DI 框架以将其传递到你的仓储构造函数中。 - Darin Dimitrov