开发者

Session Per Presenter NHibernate Desktop App - Not loading latest data from database

I'm writing a WPF NHibernate Desktop App using Session Per Presenter. I have a list view showing all the saved SalesOrders and an Edit Sales Order form when you double click on a Sales Order.

Each of these forms has a Session Object which lasts for the lifetime of the form. When a SalesOrder is saved it publishes an Event which tells the list view to re-load. The EditForm is definitely saving to the database and the ListView is definitely selecting from the database. However, the session that belongs to the ListViewPresenter is not updating its entities with those retrieved from the database. It just returns the same values as when the listSession was first loaded before anything was saved.

Below is some code which best replicates the scenario:-

        [Test]
    public void SessionPerPresenter()
    {
        //This session is the one that is used to load all salesorders from the      database. It's lifetime is the lif开发者_JS百科etime of the form but as you double click on an entry in the list to edit it will stay alive longer than the session in the edit form
        ISession listSession = NHibernateHelper.OpenSession();

        SalesOrder order = new SalesOrder("P123435", "ACME");
        order.AddLine(new SalesOrderLine("Beans", 15));
        order.AddLine(new SalesOrderLine("Coke", 24));
        order.AddLine(new SalesOrderLine("Pepsi", 3));
        order.AddLine(new SalesOrderLine("Apples", 4));

        //this session is the equivalent of the one in the Edit Form as soon as the entity is Saved
        //the session is disposed
        using (ISession session = NHibernateHelper.OpenSession())
        {
            session.SaveOrUpdate(order);
            ID = order.SalesOrderID;
        }

        //retrieve all SalesOrders from the database and store them in a list
        IList<SalesOrder> salesOrders = listSession.CreateCriteria<SalesOrder>().List<SalesOrder>();
        foreach (SalesOrder so in salesOrders)
        {
            Console.WriteLine(so.ToString());
        }

        //edit the selected order and update its order code value and resave
        using (ISession session = NHibernateHelper.OpenSession())
        {
            hydratedSalesOrder = session.Get<SalesOrder>(ID);
            hydratedSalesOrder.OrderCode = "1234-5678";
            session.SaveOrUpdate(hydratedSalesOrder);
            session.Flush();
        }

        //re-retrieve the list of orders from the database. Using SQLServer Profiler / NHibernate profiler
        //you can see the query being sent to the database so I don't believe it is in the cache. Indeed, if you run
        //the query directly against the database the value 1234-5678 is returned. Can't work out why
        //the listSession does not have the values read from the database in it but has the values from the
        //original list retrieval.
        salesOrders = listSession.CreateCriteria<SalesOrder>().List<SalesOrder>();
        foreach (SalesOrder so in salesOrders)
        {
            Console.WriteLine(so.ToString());
        }
        listSession.Close()
    }

Can someone help me with what is going on here? What am I doing wrong? Am I missing something vital? If it didn't query the database I would think it was something to do with the first level cache but that seems unlikely.


On way to ensure that your entities are not cached is to clear the session with ISession.Clear(). Also you can evict individual entities by calling ISession.Evict(object entity).

If you not sure of what is happening in your application, consider a profiling tool such as nhprof.

Quick note: using a session for the lifetime of a dialog can be handy in small applications with no concurrency problems, but you will get in trouble on the long run. A session should be opened late, and closed early.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜