Preloading IUserType with values from webservice
This post:
http://kennytordeur.blogspot.com/2011/04/nhibernate-in-combination-with_06.html
Describes how to load an entity from a resource other than a database, in this case a webservice. This is gre开发者_如何学运维at, but if I load a number of clients in one query, each with a different MaritialState, it will have to call the webservice for each Client. Is there a way to preload all marital states, so it doesn't have to go back and forth to the webservice for each client?
I don't think Hibernate supports this. 'n+1 select problem' is a well know issue and Hibernate has quite a few strategies for dealing with it (batches, subselects, eager fetching etc). The problem is you have 'n+1 web service call' and all these mechanisms are useless. Hibernate simply does not know about what you are doing in IUserType. It assumes that you converting already loaded data.
It looks like you will have to implement your own preloading. Something like this:
// TODO: not thread safe, lock or use ConcurrentDictionary
static IDictionary<Int32, ClientDto> _preLoadedClients
= new IDictionary<int,ClientDto>();
public Object NullSafeGet(IDataReader rs, String[] names, ...) {
Int32 clientid = NHibernateUtil.Int32.NullSafeGet(rs, names[0]);
// see if client has already been preloaded:
if(_preLoadedClients.ContainsKey(clientid)) {
return _preLoadedClients[clientid];
}
// load a batch: clientId + 1, client + 2, ... client + 100
var batchOfIds = Enumerable.Range(clientid, 100);
var clientsBatch = clientService.GetClientsByIds(batchOfIds);
_preLoadedClients.Add(clientsBatch);
return _preLoadedClients[clientid];
}
精彩评论