当我们尝试删除分离的代理时,nhibernate会抛出一个映射异常:
NHibernate.MappingException: No persister for: SomeClassProxy
bei NHibernate.Impl.SessionFactoryImpl.GetEntityPersister(String entityName)
bei NHibernate.Impl.SessionImpl.GetEntityPersister(String entityName, Object obj)
bei NHibernate.Event.Default.DefaultDeleteEventListener.OnDelete(DeleteEvent event, ISet transientEntities)
bei NHibernate.Impl.SessionImpl.FireDelete(DeleteEvent event)
bei NHibernate.Impl.SessionImpl.Delete(Object obj)
...
对象已分离,因为它们是主要加载的,以便向用户显示它们。因此会话在加载后关闭。
我们已经尝试使用Session.Lock
重新附加它们但是失败并出现相同的异常。
通常,此类异常的原因似乎是错误的实现拦截器。但我们不使用任何拦截器......
删除分离代理的正确方法是什么?
为什么nhibernate不能识别这些对象是代理并为基类型选择持久性?
我们正在使用NHibernate 3.3.1。
答案 0 :(得分:1)
我不确切地知道你为什么会遇到这个问题。可能有办法避免它。
但是,有一种解决方法。
var attachedEntity = session.Get<MyType>(mayBeProxy.Id);
session.Delete(attachedEntity);
你想要实现它更通用(因为你可能在编译时不知道Type),你可以像这样实现它。 (将某些内容放入辅助方法中。)
// find actual type and unproxy the entity
object unproxiedEntity = mayBeProxy;
INHibernateProxy proxy = mayBeProxy as INHibernateProxy;
if (proxy != null)
{
unproxiedEntity = proxy.HibernateLazyInitializer.GetImplementation();
}
var type = unproxiedEntity.GetType()
您可以直接删除未经批准的实体
session.Delete(unproxiedEntity);
如果这种情况失败,因为未经代理的实体不在会话中,请通过访问元数据并从会话中加载来获取其ID。
// get the ID of the entity
var metaData = session.SessionFactory.GetClassMetadata(type);
var id = metaData.GetIdentifier(unproxiedEntity);
// load the entity and delete it
var attachedEntity = session.Get(type, id);
session.Delete(attachedEntity);