我的实体看起来像这样简化:
我使用xml文件映射。我有一个表和每个类的xml文件,除了抽象的。由于我使用延迟加载,我有很多代理。奇怪的是当我调用Refresh(obj)
时,其中一个它每次都有效,除非该对象是Product1Proxy或Product2Proxy类型。然后我得到一个“没有persister for ... Proxy”错误。
我尝试了什么?
<mapping assembly="Project.DomainModel"/>
添加到App.config 我的NHibernate版本是3.3。
我的最后一个想法是我应该为我的产品使用另一个映射,但为什么它可以与CustomerProxy(和其他人)一起使用呢?在我看来,Customer和BaseObject与Product和Product1具有相同的关系。
可能是继承映射吗?我还没有看到另一个问题吗?
更新:现在我尝试在对象上调用Refresh(obj)
之前取消对它们的修改,但该方法仍然会返回Product1Proxy。然后我尝试myObject is INHibernateProxy
,但总是评估为假。为什么NHibernate不能识别自己的代理?
update2:我刚注意到,类型为Product1Proxy的myObject声明其baseobject是 Product 而不是 Product1 。我完全错了还是应该这样呢?
UPDATE3:
session.Refresh((NHibernate.Proxy.INHibernateProxy)product);
例如,这会导致无效的强制转换异常(Product1Proxy无法强制转换为INHibernateProxy)。
if (kitProduct is NHibernate.Proxy.INHibernateProxy) {
...
}
永远不会是真的......
如果我称之为
IList kitProductTemplates = ProductManager.Instance.LoadProductTemplates(checkBoxShowHidden.Checked);
Product1的列表(返回真实的Product1,没有Proxies),但如果我使用foreach迭代该列表,则对象是Proxy。查询如下所示:
public IList LoadAllTemplates(bool showHidden)
{
IList loadedObjects = (IList)new ArrayList();
try
{
ISession session = HibernateSessionManager.Instance.GetSession();
ICriteria crit = session.CreateCriteria(typeof(Product1));
crit.Add(Restrictions.Eq("IsTemplate", true));
crit.SetResultTransformer(new DistinctRootEntityResultTransformer());
crit.AddOrder(Order.Asc("Name"));
crit.SetFetchMode("PickingList", FetchMode.Join);
crit.SetFetchMode("SOP", FetchMode.Join);
if (!showHidden) {
crit.Add(Restrictions.Eq("IsHidden", false));
}
loadedObjects = crit.List();
}
catch (Exception ex)
{
throw (ex);
}
return loadedObjects;
}
(我刚发现,否则我会早点补充)
update4:我可以再次缩小问题范围。当对象首次加载时,它不会发生。但我无法保证每个可能的用例。
最好的问候,Expecto
答案 0 :(得分:0)
您应该有代理的抽象类的映射。
代理是根据可用于NH的信息生成的,而不会触及数据库(这是拥有代理的全部意义)。当您引用Product
(可能是Product1
或Product2
)时,NH会生成一个继承自Product
(ProductProxy
)的代理。要知道代理实际上应该是Product1
还是Product2
,它必须触及数据库,这不是我们想要的。
要解决此问题:使用子类或连接子类映射Product
并映射Product1
和Product2
。避免引用BaseObject
,以避免生成BaseObjectProxy
。
修改:如果您仍需要引用BaseObject
,请使用<any>
。
编辑2 :请注意,您永远不知道是否从查询中获取代理,除非您处于事务的开头。每当为产品创建代理时,NH都会从返回相同产品的每个查询中继续返回此代理。即使查询不会返回代理。这是为了确保您始终为同一事物获得相同的实例。
示例:
在DB中,您拥有ID为1,2和3的Product1。
// NH creates a proxy.
var proxy = session.Load<Product>(1);
// NH returns all Product1 instances, including the proxy
var allProducts = session.CreateCriteria(typeof(Product1)).List();
allProducts包含ID为1的代理和ID为2和3的非代理。