1

It appears that is a best practice to put all the database calls into a transaction. So, I wanted to put a select action in a transaction, but I can't find how to do this.

I have tried this code, but I get an error:

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;
}

Error:

Session is closed! Object name: 'ISession'.

cspolton
  • 4,495
  • 4
  • 26
  • 34
Martijn
  • 24,441
  • 60
  • 174
  • 261

1 Answers1

3

It's not a matter of Transaction itself, although I only use transactions for save/update calls, not selects, but that might be a matter of preference (or I simply don't know something important).

The thing is, you're not 'materializing' the collection before closing the session. This should work:

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

return result;

The Where does not do anything by itself. Which means you're just deferring execution of the filter until you do something with it - e.g. iterate over it. If you're out of Session scope by then (and it seems you are), you'll get the exception, since you can't call the database when the session is closed.

Although you probably won't be able to access lazily loaded child items without eagerly Fetching them first - you can't call database through proxy when you're not inside an open session. :)

Disclaimer

By the way, same thing would happen in EF with LINQ:

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.
}
Patryk Ćwiek
  • 14,078
  • 3
  • 55
  • 76
  • 1
    Regarding the initial sentence: Save/Update calls do not (always) trigger a write to the database. More importantly, they are not the only way to cause write. With NHibernate default settings, any query may trigger writes if objects loaded in the session have been modified and might affect the query results. – Oskar Berggren Sep 04 '12 at 07:45