2

我将 .net 2.0 与 NHibernate/ActiveRecord 和 WCF 一起使用。

到目前为止我还没有使用过 NH Lazy load,但是性能损失太大而无法忽略,所以我开始使用它。

从我目前所读到的内容来看,这不是一个简单的主题,使用具有延迟加载和序列化到 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 是两个不相关的实体,但它们是相同的实体,例如 Branch 200 具有 DefaultPOSCustomer 100,而 POSCustomer 具有 BelongsToBranch 200。

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

如果我在这些类上关闭 Lazy = true,则序列化工作得很好。

  1. DataContractSerializer 如何判断一个实体已经被序列化了?
  2. 我怎样才能阻止这种行为?
  3. 是否有其他方法可以使用 WCF 序列化延迟加载实体?

ps 我一直在考虑另一种解决方案,创建类似于 NHibernate Proxy 的东西,但是用原始键替换与其他类相关的属性,所以我没有一个 Branch 类型的属性,而是一个类型的属性int 的值为 200。这样我也许可以避免我遇到的循环问题,但我会尝试将此作为最后的手段,因为维护起来会非常复杂。

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

编辑:好吧,直接 NH/AR/WCF 的方式不走运。我将继续创建似乎更容易的 DTO。

4

3 回答 3

2

我只是注意到我没有结束我的问题,我使用了 DTO 解决方案,到目前为止它工作得很好。

于 2009-09-13T11:18:23.657 回答
0

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

于 2009-09-10T20:00:44.600 回答
0

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

于 2011-01-18T21:37:31.107 回答