1

将所有数据库调用放入事务中似乎是最佳实践。所以,我想在事务中放置一个选择操作,但我找不到如何做到这一点。

我已经尝试过这段代码,但出现错误:

using (var session = GetSession().SessionFactory.OpenSession())
using (var transaction = session.BeginTransaction())
{
    // var session = GetSession();
    var result = session.Query<I>().Where(condition);

    transaction.Commit();

    return result;
}

错误:

会话关闭!对象名称:'ISession'。

4

1 回答 1

3

这不是问题Transaction本身,虽然我只使用事务进行保存/更新调用,而不是选择,但这可能是一个偏好问题(或者我根本不知道一些重要的事情)。

问题是,在关闭会话之前,您并没有“实现”集合。这应该有效:

var result = session.Query<I>.Where(condition).List();

return result;

Where本身不做任何事情。这意味着您只是推迟执行过滤器,直到您对它进行某些操作- 例如对其进行迭代。如果到那时您已超出 Session 范围(看起来您已经超出了),您将收到异常,因为在会话关闭时您无法调用数据库。

尽管您可能无法访问延迟加载的子项而不Fetch先急切地访问它们 - 当您不在打开的会话中时,您无法通过代理调用数据库。:)

免责声明

顺便说一句,同样的事情会发生在带有 LINQ 的 EF 中:

IEnumerable<I> myObjects;

using(var context = new MyDbContext())
{
    myObjects = context.Set<I>.Where(x => x.Name == "Test");
}

foreach(obj in myObjects)
{
    var name = obj.Name; //BOOM! Context is disposed.
}
于 2012-08-31T11:14:27.653 回答