The first question you have to ask yourself is, "Do I want the user to lose their order completely if they don't explicitly Save it before they close their browser or their Session times out?"
If the answer is NO, then your solution is simple: save the order to the database immediately with an Incomplete flag set.
If you do not care if they customers lose their order if they dont' Save them, then you have a few choices.
1. You can store the Order object in the ViewState.
Code:
protected Order _order
{
get
{
return (Order)ViewState["_order"];
}
set
{
ViewState["_order"] = value;
}
}
ViewState is stored in a hidden input field. That means it will exist for as long as the user keeps their browser window open on that page and no longer. However, if the user opens a new browser window, they won't be able to see orders that are in the ViewState of another window.
2. You can store the Order object(s) in the Session. Sessions time out after a set period of time. Furthermore, the user will get disconnected from the Session if they close their browser (since the SessionID cookie is a temporary one), but the Session will not time out immediately. Session also get destroyed if the Application restarts, which can happen at any time (any time your app reaches a certain memory limit, it will get automatically recycled). For this last reason, I follow the rule "Don't write to the Session anywhere other than Session_Start." In general, be very, very careful with use of the Session. Be aware of how much data you are putting in the Session and never put anything with unmanaged resources (like DB connections or file handles) in the Session.
3. You can store the object in the HttpContext.Cache. This gives you much, much more control over how long the object stays in server memory. IIRC, Session is just a wrapper around Cache anyhow. Unlike Session, Cache is independant of the user's SessionID cookie. Cache will still dissappear if the application restarts, however. Using the Cache will require a good bit of RTFM-fu, but it's worth it for lots of other things as well. The built-in Cache functionality in ASP.NET is very cool.
You might look into the "Second Level Cache" functionality in NHibernate.Contrib as well. I haven't quite RTFM'd that deep yet since I haven't needed it on any of my NHibernate-using projects yet.