I have an interesting scenario in an application that I am working on. 
Using the familiar analogy, my entities look something like this:

public class Customer
{
    public virtual ISet<Order> Orders { get; set; }
}

public class Order
{
   // ...
}

A Customer has a (potentially large, 250k or more) collection of Orders. Of 
course, these are not my real entities, these are just to give you an idea 
of their shape.

For this use case, I need to create a complete copy of the Customer, 
including the Orders.  To prevent NH from loading all of the Orders into 
memory and doing an app level copy, I am pulling an end-run around the 
session and using a SQL query to copy the Orders forward. This works like a 
charm.  However, things get tricky when I want to work with the new copy of 
the Customer. Since NH doesn't know what the SQL did, it thinks that the 
new Customer's Orders collection is empty.

I basically need a way to tell the session that I did some stuff behind its 
back and that the Orders collection is stale. These are the things I have 
tried so far:

1. Session.Refresh(newCustomer) - this works well for orders with a small 
number of orders, but for large numbers of Orders is incredibly slow since 
NH (sensibly) tries to refresh all of the data for the Customer and Orders.
2. Session.Evict(newCustomer) - I get a KeyNotFoundException here (after a 
few second delay) that I don't fully understand. I assume that somewhere in 
my object graph, an entity which is not owned by the session is being 
evicted, possibly because I have some types that are mapped as IUserTypes 
in there. Not sure on that though.
3. Session.Evict(newCustomer.Orders) - I was hoping this would cause just 
the Orders collection to get expired, but it actually seems to have no 
effect since the set is not actually owned by the session.
4. Using a new session - this works, but is easy to mess up.  This logic 
could end up getting duplicated across many parts of the application if we 
need to  copy any other entities with large collections in them. It also 
doesn't keep the persistence as transparent as I would like. However, if 
necessary, this may be a workable solution.
5. Session.Clear() - this also has no effect which makes sense because I am 
pretty sure clearing the Session really just means to expire the first 
level cache, and that is not the issue in this case.

Ideally, I would like to replace the Orders collection with an 
uninitialized proxy so that NH would go to the DB and pull back the orders 
on the next request. This would prevent me from needing to refresh the 
entire Customer object and allow me to only load the Orders if necessary. 
Something like session.MarkStale(customer.Orders) would be great.

-- 
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/nhusers/-/eqF6XvzUSPYJ.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en.

Reply via email to