使用webservice的值预装IUserType [英] Preloading IUserType with values from webservice

查看:110
本文介绍了使用webservice的值预装IUserType的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这篇文章:

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



介绍如何从数据库以外的资源加载实体,在这种情况下是web服务。这很好,但是如果我在一个查询中加载了多个客户端,每个客户端都有一个不同的MaritialState,它将不得不为每个客户端调用Web服务。有没有办法预先加载所有的婚姻状态,所以它不必为每个客户端来回访问网络服务? 解决方案

我不认为Hibernate支持这个。 'n + 1选择问题'是一个众所周知的问题,Hibernate有很多处理它的策略(批处理,子查询,提取等)。问题是你有'n + 1网络服务调用',所有这些机制都没用。 Hibernate根本不知道你在IUserType中做什么。它假定你已经转换已经加载的数据。



看起来你必须实现自己的预加载。像这样:

  // TODO:没有线程安全,锁定或使用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]);

//查看客户端是否已经预加载:
if(_preLoadedClients.ContainsKey(clientid)){
return _preLoadedClients [clientid];
}

//加载一个批次:clientId + 1,client + 2,... client + 100
var batchOfIds = Enumerable.Range(clientid,100);
var clientsBatch = clientService.GetClientsByIds(batchOfIds);

_preLoadedClients.Add(clientsBatch);

return _preLoadedClients [clientid];
}


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 great, 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];
}

这篇关于使用webservice的值预装IUserType的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆