NHibernate的序列化与WCF延迟加载实体 [英] NHibernate serializing lazy-loaded entities with WCF

查看:174
本文介绍了NHibernate的序列化与WCF延迟加载实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图通过使用WCF对金属线送NH实体。我有懒加载的对象..
我试图实现自定义序列化DataContractSurrogate时强制初始化一个复杂的图形。
下面是代码:

 公共类HibernateDataContractSurrogate:IDataContractSurrogate 
{
公共HibernateDataContractSurrogate( )
{
}

公共类型GetDataContractType(类型类型)
{
//序列化代理为基本类型
如果(typeof运算(INHibernateProxy).IsAssignableFrom(类型))
{
型= type.GetType()基本类型。
}

//序列化持久化集合作为集合接口类型
如果(typeof运算(IPersistentCollection).IsAssignableFrom(类型))
{
的foreach(在type.GetInterfaces类型collInterface())
{
如果(collInterface.IsGenericType)
{
型= collInterface;
中断;
}
,否则如果
{
型= collInterface(collInterface.Equals(typeof运算(IPersistentCollection))!);
}
}
}

返回类型;
}

公共对象GetObjectToSerialize(obj对象,类型TARGETTYPE)
{
如果(obj是INHibernateProxy)
{
OBJ =( (INHibernateProxy)物镜).HibernateLazyInitializer.GetImplementation();
}

//序列化持久化集合作为集合接口类型
如果(obj是IPersistentCollection)
{
IPersistentCollection persistentCollection =(IPersistentCollection)目标文件;
persistentCollection.ForceInitialization();
OBJ = persistentCollection.Entries(NULL); //这将返回包装集合
}

返回OBJ;
}

公共对象GetDeserializedObject(obj对象,类型TARGETTYPE)
{
返回OBJ;
}

公共对象GetCustomDataToExport(的MemberInfo的MemberInfo,类型dataContractType)
{
返回NULL;
}

公共对象GetCustomDataToExport(类型clrType,类型dataContractType)
{
返回NULL;
}

公共无效GetKnownCustomDataTypes(收集和LT;类型> customDataTypes)
{
}

公共类型GetReferencedTypeOnImport(字符串typeName的,字符串typeNamespace ,的CustomData对象)
{
返回NULL;
}

公共CodeTypeDeclaration ProcessImportedType(CodeTypeDeclaration typeDeclaration,CodeCompileUnit compileUnit)
{
返回typeDeclaration;
}
}



不过,我不断收到异常:



  NHibernate.Exceptions.GenericADOException:无法初始化集合[SQL跟踪] ---> System.ObjectDisposedException:会话被关闭! 



综观堆栈跟踪,看来这行 persistentCollection.ForceInitialization() ;
抛出异常



我能做些什么



<? p> PS:我想,而不是使用序列化复杂NH实体DTO,但它是不可能在这里


解决方案

您可你关闭从它被装在 NHibernate.ISession 对象后不懒加载的集合。你唯一的选项是:




  1. 保留的Isession 开放,直到你序列化的数据。

  2. 关闭延迟加载。

  3. 确保您在会议结束前获取所有延迟加载的集合。


I'm trying to send NH entities through the wire using WCF. I've got a complex graph of lazy-loaded objects.. I tried to implement a custom DataContractSurrogate to force initialization when serializing. Here is the code :

public class HibernateDataContractSurrogate : IDataContractSurrogate
{
    public HibernateDataContractSurrogate()
    {
    }

    public Type GetDataContractType(Type type)
    {
        // Serialize proxies as the base type
        if (typeof(INHibernateProxy).IsAssignableFrom(type))
        {
            type = type.GetType().BaseType;
        }

        // Serialize persistent collections as the collection interface type
        if (typeof(IPersistentCollection).IsAssignableFrom(type))
        {
            foreach (Type collInterface in type.GetInterfaces())
            {
                if (collInterface.IsGenericType)
                {
                    type = collInterface;
                    break;
                }
                else if (!collInterface.Equals(typeof(IPersistentCollection)))
                {
                    type = collInterface;
                }
            }
        }

        return type;
    }

    public object GetObjectToSerialize(object obj, Type targetType)
    {
        if (obj is INHibernateProxy)
        {
            obj = ((INHibernateProxy)obj).HibernateLazyInitializer.GetImplementation();
        }

        // Serialize persistent collections as the collection interface type
        if (obj is IPersistentCollection)
        {
            IPersistentCollection persistentCollection = (IPersistentCollection)obj;
            persistentCollection.ForceInitialization();
            obj = persistentCollection.Entries(null); // This returns the "wrapped" collection
        }

        return obj;
    }

    public object GetDeserializedObject(object obj, Type targetType)
    {
        return obj;
    }

    public object GetCustomDataToExport(MemberInfo memberInfo, Type dataContractType)
    {
        return null;
    }

    public object GetCustomDataToExport(Type clrType, Type dataContractType)
    {
        return null;
    }

    public void GetKnownCustomDataTypes(Collection<Type> customDataTypes)
    {
    }

    public Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData)
    {
        return null;
    }

    public CodeTypeDeclaration ProcessImportedType(CodeTypeDeclaration typeDeclaration, CodeCompileUnit compileUnit)
    {
        return typeDeclaration;
    }
}

However, I keep getting exceptions :

NHibernate.Exceptions.GenericADOException: could not initialize a collection [SQL trace] ---> System.ObjectDisposedException: Session is closed!

Looking at the stacktrace, it appears that this line persistentCollection.ForceInitialization(); is throwing the exception.

What can I do?

PS: I'd like to use DTO instead of serializing complex NH entities, however it's not possible here.

解决方案

You can't lazy-load a collection after you've closed the NHibernate.ISession object from which it was loaded. The only options you have are:

  1. Keep the ISession open until you've serialized the data.
  2. Turn off lazy loading.
  3. make sure you fetch all the lazy loaded collections before closing the session.

这篇关于NHibernate的序列化与WCF延迟加载实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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