NHibernate-just select的最佳实践

NHibernate-just select的最佳实践,nhibernate,transactions,Nhibernate,Transactions,A在我的MVC应用程序上有一个操作,该操作具有id,并返回一个人的姓名 这方面的最佳做法是什么?我在遵循NHProf的提示,但代码听起来有点奇怪,或者对我来说有些什么 using (var session = Helper.SessionFactory.OpenStatelessSession()) { using (var tran = session.BeginTransaction(IsolationLevel.ReadCommitted)) { retur

A在我的MVC应用程序上有一个操作,该操作具有
id
,并返回一个人的姓名

这方面的最佳做法是什么?我在遵循NHProf的提示,但代码听起来有点奇怪,或者对我来说有些什么

using (var session = Helper.SessionFactory.OpenStatelessSession())
{
    using (var tran = session.BeginTransaction(IsolationLevel.ReadCommitted))
    {
        return session.Query<Person>().Where(x => x.Id == id).Select(x => x.Name).SingleOrDefault();
        tran.Rollback();
    }
}
使用(var session=Helper.SessionFactory.OpenStatelessSession())
{
使用(var-tran=session.BeginTransaction(IsolationLevel.ReadCommitted))
{
return session.Query().Where(x=>x.Id==Id);
事务回滚();
}
}

NHProf警报页面对此进行了很好的解释,我认为-

基本上是说,如果您自己不管理事务,数据库将为每个语句(包括查询)创建一个“隐式事务”和自动提交。误解是事务只对插入/更新操作有用


在上面的示例中,这不是什么问题,因为您的事务只执行一条语句。但是,如果您的方法运行多个语句,最好将它们包装在事务中。

下面是我如何处理此选择的方法:

    using (var session = Helper.SessionFactory.OpenStatelessSession())
    using (var tran = session.BeginTransaction(IsolationLevel.ReadCommitted))
    {
        try
        {
            string personName = session.Query<Person>()
            .Where(x => x.Id == id)
            .Single(x => x.Name);

            tran.Commit();
            return personName;
        }
        catch(Exception ex)
        {
            // handle exception
            tran.Rollback();
        }
    }
使用(var session=Helper.SessionFactory.OpenStatelessSession())
使用(var-tran=session.BeginTransaction(IsolationLevel.ReadCommitted))
{
尝试
{
字符串personName=session.Query()
.其中(x=>x.Id==Id)
.Single(x=>x.Name);
trans.Commit();
返回人名;
}
捕获(例外情况除外)
{
//处理异常
事务回滚();
}
}
此答案为处理事务提交提供了很好的建议:

关于LINQ,这是一篇关于如何不使用扩展方法样式语法处理查询的有趣文章:


不要在一个HTTP请求上创建多个会话,理想情况下,您需要在请求范围内打开一个会话和相应的事务,并在所有操作中使用此会话

以下是一篇博客文章,解释如何实现这一目标:

我建议使用一个IOC容器,创建一个类来为您创建会话,并将这个类的作用域设置为请求作用域


网络上有很多资源来解决这个问题。。谷歌it..

我不明白为什么它会建议进行事务处理…我不会使用
OpenStatelessSession
无状态会话用于批量场景,并忽略一级缓存。与其做linq查询,我只需调用
.Load(1)
.Get(1)
,这表示的不仅仅是linq查询。好的,但是对于简单的方法,我是否应该遵循NHProf并创建事务?答案只是部分正确,您应该始终在事务中扭曲您的数据库查询,事实上,即使您执行一条语句,这也将是一个问题。隐式事务非常昂贵!NH不会在没有事务的情况下使用二级缓存。-1用于捕获所有内容,执行冗余工作(使用和尝试捕获)。@Andreas就我所知,使用无法处理抛出的异常,可以选择使用冗余尝试或手动处理。另外,在这种情况下,由于有许多层可能抛出错误,您将如何实现错误处理(NHibernate、ADO.NET、LINQ)。对于异常,请不要告诉我您可以使用
tran.Rollback()正确处理堆栈溢出、内存不足exc。感谢链接,我不知道事务被隐式回滚。另外,我应该在Rollback()之后放置“//handle exception”,因为我打算将其作为错误处理的占位符。我很欣赏你所说的关于捕获所有异常处理的话,这可能不是最好的做法。虽然每个请求一个会话是合理的建议,但这不是一个硬性规定,每个请求一个事务是糟糕的建议,简单明了。