2009-04-19 22 views
2

NHibernate/ActiveRecordとWCFで.net 2.0を使用しています。wcfシリアライズとnhibernate遅延ロード

これまでのところ、NH遅延ロードを使用していませんでしたが、パフォーマンスのペナルティは無視するには大きすぎるため、使用し始めています。

これまで読んだことは、NHエンティティを使用して遅延読み込みとWCFへのシリアライズを行うことは簡単なことではありませんが、その利点は無視するには大きすぎます。

ここで私が見つけたコードを使用してください: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は無関係な2つのエンティティですが、それらは同じエンティティです例Branch 200はDefaultPOSCustomer 100を持ち、POSCustomerはBelongsToBranch 200を持っています。

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

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

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

p.s.私は別の解決策、NHibernateプロキシに似て何かを作成しているが、ブランチタイプのプロパティを持つ代わりに、他のクラスに関連するプロパティを生のキーに置き換えて、私はint型のプロパティを持つだろうこのようにして私が遭遇したサイクルの問題を避けることができるかもしれませんが、これを最後の手段として試してみましょう。これは、維持するのがかなり複雑なためです。

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

編集:うーん、運が直接NH/AR/WCF方法です。私はDTOを作るのと一緒に行くつもりです。

+1

ウェブサービスに使用するDTOを作成してみませんか? – Paco

答えて

2

私は私の質問を終わらせていないことに気付きました。私はDTOソリューションを使いました。これまでのところうまくいきました。

0

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

0

我々はthis溶液を使用しており、それがDTO溶液よりも容易であることを発見した。

関連する問題