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.