2

NHibernate/ActiveRecord と WCF で .net 2.0 を使用しています。

これまで NH Lazy load を使用していませんでしたが、パフォーマンス ペナルティが大きすぎて無視できないため、使用し始めています。

私がこれまでに読んだことから、遅延読み込みと WCF へのシリアル化を備えた NH エンティティを使用することは簡単なテーマではありませんが、その利点は無視するには大きすぎます。

ここで見つけたコードを使用: WCF Serialization 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 は 2 つの無関係なエンティティですが、同じエンティティです。たとえば、Branch 200 には DefaultPOSCustomer 100 があり、POSCustomer には BelongsToBranch 200 があります。

問題は、WCF がオブジェクト グラフをシリアル化しようとすると、DefaultPOSCustomer と BelongsToBranch の間で、それらが同じエンティティであり、既にシリアル化されていることを認識しないかのように、スタック オーバーフローが発生するまでバウンスすることです。

これらのクラスで Lazy = true をオフにすると、シリアル化は正常に機能します。

  1. DataContractSerializer は、エンティティが既にシリアル化されていることをどのように判断しますか?
  2. どうすればこの動作を停止できますか?
  3. WCF を使用して遅延読み込みエンティティをシリアル化する他の方法はありますか?

ps NHibernate Proxyに似たものを作成するという別の解決策を検討していましたが、他のクラスに関連するプロパティを生のキーに置き換えるため、タイプBranchのプロパティを持つ代わりに、タイプのプロパティを持つことになります値 200 の int です。この方法で、私が遭遇したサイクルの問題を回避できるかもしれませんが、維持するのがかなり複雑になるため、最後の手段としてこれを試してみます。

編集:私はたくさんのエンティティを持っているので、それぞれに dto を作成することは問題外であり、動的に作成するのは複雑になるので、それを避けるか、最後の手段として使用したいと思います. また、サーバー側でビジネス ロジックを実行する必要があるため、生データではなくエンティティが必要になります。

編集:まあ、NH/AR/WCF の直接の方法で行く運はありません。簡単に思える DTO を作成します。

4

3 に答える 3

0

このソリューションを使用してきましたが、DTO ソリューションよりも簡単で優れていることがわかりました。

于 2011-01-18T21:37:31.107 に答える
0

答えるには遅すぎます ;-) とにかく、遅延ロードされたオブジェクトが NH プロキシ クラスであるため、これが発生します。このようにロードすると、それらは異なるようです。1 つの解決策は、.Equals() をオーバーライドして、永続エンティティの Id プロパティを比較することです。あなたのエンティティには主キーのようなものがあると思います。これはおそらく、参照比較ではなく等価性を使用する場合にのみ、WCF を満足させるでしょう。WCF が常に ReferenceEquals を使用する場合 - うまくいきません。

于 2009-09-10T20:00:44.600 に答える