6

コンテキスト:用いたナビゲーションプロパティ

  • コードまず、Entity Frameworkの4.3.1。
  • ユーザー----トピック、1 to Many relation;
  • Userpublic virtual ICollection<Topic> CreatedTopicsナビゲーションプロパティ(レイジーロード)。
  • Topicpublic virtual User Creatorナビゲーションプロパティ。
  • DataServiceController : DbDataController<DefaultDbContext>、Web APIベータ版、ASP.NET MVC 4ベータ版、シングルページアプリケーション。
  • Jsonシリアル化のためのSystem.Json;
  • ウェブAPIアクション:

    public IQueryable<Topic> GetTopics() 
    { 
        // return DbContext.Topics;     // OK 
        return DbContext.Topics.Include("Creator"); //With Exception 
    } 
    
  • 結果:

を "未処理のMicrosoft .NET Frameworkの例外がw3wp.exeの中で発生しました" ここでの問題はあると思われる:私がすべき両方のエンティティのナビゲーションプロパティを追加します(原因循環参照?)CreatedTopicsナビゲーションプロパティをUserクラスで削除すると、もう一度OKにしてください。

ので、上記のような同様のコンテキストでは、ここに私の質問は以下のとおりです。

  1. 多く関係に1の状況でナビゲーションプロパティをどのように扱いますか。
  2. さらに詳しい情報は多対多の関係、2つに分割する必要がありますか1 to manyリレーションシップ、
  3. ナビゲーションプロパティを使用する際のベストプラクティスと注意事項は何ですか?

私は多くの関連記事を読んで、しかしまだ十分明確ではないか:(、任意の助け

感謝を

ディーン

答えて

9

をこれが最初のコードの問題やEFではありません! - Web APIメッセージで渡された表現にオブジェクトグラフを変換するために使用されるシリアライザは、デフォルトで循環参照では動作しません。Web APIを使用するメッセージフォーマットによっては、異なるシリアライザが使用されますデフォルトで - hereはもっとaですWeb APIで使用されるデフォルトのシリアライザとその変更方法について説明します。次のテキストはDataContractJsonSerializerまたはDataContractSerializerを使用していると仮定しています(XMLシリアル化ではデフォルトにする必要があります)がJSONの場合はデフォルトである必要があります(JSONのシリアル化はDataContractJsonSerializerに切り替えることができますが、 。

あなたは何ができますか?シリアライザでは、クラスをDataContract(IsReference = true)でマークし、それぞれのプロパティにDataMemberという属性を付けて循環参照を追跡するように指示できます(JSON.NETで達成する方法についてはリンクされた記事を参照してください)。シリアライザがサイクルを正しく認識できるようになり、理論的にはシリアル化が成功するでしょう。なぜなら、これはまた、遅延ロードを使用しないことを要求するからです。さもなければ、予想以上に多くのデータをシリアライズすることができます(致命的なシナリオでは、データベースの全内容をシリアライズする可能性があります)。あなたが遅延ロードとエンティティグラフをシリアル化

あなたはTopicとそのCreatorをserailze有効ですが、連載もCreatedTopicsプロパティ=>すべての関連トピックがロードされ、直列化および直列化によって処理怠け者です訪問することは、すべて新たにロードされた話題のCreatorを訪問し続け!このプロセスは、遅延ロードするオブジェクトがなくなるまで続きます。このため、エンティティを直列化するときに遅延ロードを使用しないでください。

その他のオプションは、シリアル化からの参照を除外することです。 Creatorをシリアル化するだけです。 IgnoreDataMember属性(JSON.NETの場合はJsonIgnore)でプロパティをマークできるように、CreatedTopicsをシリアル化する必要はありません。問題は、Userをすべて返して返すWeb APIアクションがある場合は、CreateTopics属性のためにこれが機能しないことです。

最後のオプションはエンティティを使用していません。このオプションは通常、特定の操作の要件を満たす特別なDTOオブジェクトを作成し、操作内のエンティティとDTO間の変換を処理するWebサービスで使用されます(AutoMapperのようなツールの助けを借りて可能です)。

1対1,1対多、または多対多の関係の処理には違いはありません。両方のナビゲーションプロパティがある場合は、常にこの問題に対処する必要があります。

+0

DataContractJsonSeriaizerは、Web APIベータ版のデフォルトJsonシリアライザですか? – Dean

+0

私は 'DataContract(IsReference = true)'と 'DataMember'を一時的に使用しています。私はDTOオプションについても興味がありますが、今は実現できず、もっと時間を費やし、良い答えに感謝します。 – Dean

関連する問題