0

I'm using a gridview in c# and am trying to delete a row. I am using nHibernate with session-per-request. My problem is when I delete and perform a row command I can delete the record in db but when I try to reload the datasource, because the delete hasn't committed yet I seem to be fetching the original data within the same session.

Can someone tell me what the best strategy is to handle this scenario?

Many thanks! Sid

Sid
  • 355
  • 1
  • 5
  • 11
  • The best scenario is to **SPLIT** write and read actions. E.g. I do use Delete to delete, then redirect to List() in MVC, or just DELETE method and then Find via GET with Web API. We should never combine these... – Radim Köhler Nov 02 '14 at 18:15
  • http://stackoverflow.com/questions/13131796/nhibernate-caching-issue-when-to-call-evict – user1618077 Nov 02 '14 at 23:04

1 Answers1

1

You should run two transactions. In WebForms, your code might look like this:

using (var transaction = Session.BeginTransaction())
{
    var foo = Session.Load<Foo>(fooId);
    Session.Delete(foo);

    transaction.Commit();
}

using (var transaction = Session.BeginTransaction())
{
    gridView.DataSource = Session.List<Foo>(fooId);
    gridView.DataBind()

    transaction.Commit();
}

Like Radim Kohler says, if you were doing this the more modern RESTful way in MVC, you should have the client make two calls to your API - a Delete call, then a List call. The principal is the same though - you need two transactions.

I'm not quite sure why NHibernate doesn't AutoFlush in your scenario, but if you are not opening a transaction at all, then you may find NHibernate's AutoFlush feature does not work as it should.

cbp
  • 25,252
  • 29
  • 125
  • 205
  • Exactly. Also, Sid, check the [FlushMode setting](http://nhforge.org/doc/nh/en/index.html#manipulatingdata-flushing), and meanwhile call explict `session.Flush()` before commit... – Radim Köhler Nov 03 '14 at 07:49
  • I'm using session-per-request with a HttpWebModule, this creates the session and a transaction at Application_BeginRequest and commit and end the session in Application_EndRequest. Is this wrong for what I would like to do? Seems like when I issue the delete command it deletes and then fetch and rebind the grid then commits the whole lot at the end of the request. Is there a way I can maybe end the transaction and commit midway through the request then start a new transaction and let the Application_EndRequest complete the rebind call? – Sid Nov 04 '14 at 11:34
  • @Sid Yes, you should only open the session on begin request and end request. You should open transactions in your controller/code-behind code. Sometimes you will have more the one transaction open per request. Transactions should be open for the minimum amount of time and should relate to one 'business action'. For example, if you are doing some user tracking in an http module you would want to execute that in it's own transaction. Note that you will need some way to access the current open session for the request (e.g. store the session variable in HttpContext.Current.Items). – cbp Nov 05 '14 at 00:45