Предварительная загрузка IUserType со значениями из веб-сервиса - PullRequest
1 голос
/ 06 сентября 2011

Этот пост:

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

Описывает, как загрузить объект из ресурса, отличного от базы данных, в данном случае веб-службы. Это замечательно, но если я загружаю несколько клиентов в одном запросе, каждый с разным MaritialState, ему придется вызывать веб-сервис для каждого клиента. Есть ли способ предварительной загрузки всех семейных состояний, чтобы не приходилось переходить туда и обратно в веб-службу для каждого клиента?

1 Ответ

1 голос
/ 07 сентября 2011

Я не думаю, что Hibernate поддерживает это. 'n + 1 проблема выбора' - это хорошо известная проблема, и в Hibernate есть немало стратегий для ее решения (пакеты, подвыборы, активное получение и т. Д.). Проблема в том, что у вас есть n + 1 вызов веб-службы, и все эти механизмы бесполезны. Hibernate просто не знает о том, что вы делаете в IUserType. Предполагается, что вы конвертируете уже загруженные данные.

Похоже, вам придется реализовать собственную предварительную загрузку. Как то так:

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