wcf序列化和nhibernate延迟加载

时间:2009-04-19 16:51:06

标签: wcf nhibernate serialization lazy-loading

我正在使用带有NHibernate / ActiveRecord和WCF的.net 2.0。

到目前为止,我还没有使用NH Lazy加载,但性能损失太大而不能忽略,所以我开始使用它。

从我到目前为止所读到的内容来看,使用延迟加载和序列化到WCF的NH实体并不是一个简单的主题,但是它的好处太大了,不容忽视。

使用我在此处找到的代码:WCF Serialization With NHibernate,我已经能够让WCF识别基本类型。

我也是这样创建DataContractSerializer:

public override XmlObjectSerializer CreateSerializer(Type standard, XmlDictionaryString name, XmlDictionaryString NS, IList<Type> knownTypes)
{
    return new DataContractSerializer(standard, name, NS, knownTypes, 0x989680, false, true /* Preserve References*/, new HibernateDataContractSurrogate());
}

我的问题是当我有这样的事情时:

[DataContract, ActiveRecord("POS_POSCUSTOMERS",Lazy = true)]
public class POSCustomer : ActiveRecordForPOS<POSCustomer>
{
    private Branch belongsToBranch;

    [DataMember,BelongsTo("BRANCH")]
    public virtual Branch BelongsToBranch
    {
        get { return belongsToBranch; }
        set { belongsToBranch = value; }
    }
}

[DataContract, ActiveRecord("BRANCHES",Lazy = true)]
public class Branch : ActiveRecordForPOS<Branch>
{
    private POSCustomer defaultPOSCustomer;

    [DataMember, BelongsTo("POS_POSCUSTNUM", Cascade= CascadeEnum.None)]
    public virtual POSCustomer DefaultPOSCustomer
    {
        get { return defaultPOSCustomer; }
        set { defaultPOSCustomer = value; }
    }
}

Branch.DefaultPOSCustomer和POSCustomer.BelongsToBranch是两个不相关的实体,但它们是相同的实体,例如Br​​anch 200具有DefaultPOSCustomer 100,而POSCustomer具有BelongsToBranch 200。

问题在于,当WCF尝试序列化对象图时,它会在DefaultPOSCustomer和BelongsToBranch之间反弹,好像不会识别出它们是相同的实体并且已经将它们序列化,直到它遇到堆栈溢出

如果我在这些类上关闭Lazy = true,序列化就可以了。

  1. DataContractSerializer如何确定实体已被序列化?
  2. 如何阻止此行为?
  3. 是否有其他方法可以使用WCF序列化延迟加载实体?
  4. P.S。我一直在考虑另一个解决方案,创建类似于NHibernate Proxy的东西,但用原始键替换与其他类相关的属性,所以我没有类型为Branch的属性,而是有一个int类型的属性这样我可以避免我遇到的循环问题,但我会尝试将其作为最后的手段,因为维护它会非常复杂。

    编辑:我有很多实体,所以为每个实体创建一个dto是不可能的,动态创建它会很复杂,所以我宁愿避免使用它,也不要将它作为最后的手段使用。我还需要在服务器端执行业务逻辑,因此我需要实体而不是原始数据。

    编辑:好吧,没有运气直接的NH / AR / WCF方式。我会选择创建看似简单的DTO。

3 个答案:

答案 0 :(得分:2)

我刚注意到我没有关闭我的问题,我选择了DTO解决方案,到目前为止工作正常。

答案 1 :(得分:0)

回答为时已晚;-)但无论如何,这是因为延迟加载的对象是NH代理类;并且看起来像这样加载时它们是不同的。 一种解决方案是覆盖.Equals()以比较持久实体的Id属性。我想你的实体有类似主键的东西。这可能会使WCF满意,只有它使用相等而不是引用比较。如果WCF总是使用ReferenceEquals - 没有运气。

答案 2 :(得分:0)

我们一直在使用this解决方案,并且发现它比DTO解决方案更容易/更好。