2011-09-06 2 views
1

Ce poste:préchargement IUserType avec des valeurs de webservice

http://kennytordeur.blogspot.com/2011/04/nhibernate-in-combination-with_06.html

Décrit comment charger une entité d'une ressource autre qu'une base de données, dans ce cas, un webservice. C'est génial, mais si je charge un certain nombre de clients dans une requête, chacun avec un MaritialState différent, il devra appeler le webservice pour chaque client. Existe-t-il un moyen de précharger tous les états matrimoniaux, de sorte qu'il ne doit pas aller et venir sur le webservice pour chaque client?

Répondre

1

Je ne pense pas que Hibernate supporte cela. 'n + 1 select problem' est un problème bien connu et Hibernate a quelques stratégies pour y faire face (lots, sous-sélections, chargement exaltant, etc.). Le problème est que vous avez un 'appel de service Web n + 1' et tous ces mécanismes sont inutiles. Hibernate ne sait tout simplement pas ce que vous faites dans IUserType. Il suppose que vous convertissez des données déjà chargées.

Il semblerait que vous deviez implémenter votre propre préchargement. Quelque chose comme ceci:

// 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]; 
}