JSONのシリアル化における再帰的参照または回覧参照を処理するには、スタックオーバーフローの例外やデータの矛盾などの問題を回避するために慎重に検討する必要があります。これらの参照を管理するためのいくつかのベストプラクティスは次のとおりです。
Circular Referencesの理解
循環参照は、オブジェクトが最初のオブジェクトを参照してループを作成する別のオブジェクトを参照するときに発生します。これは、JSONのシリアル化中に問題を引き起こす可能性があります。これは、無限の再帰につながるためです。
##循環参照を処理するための手法
1。円形の参照を避ける**
ベストプラクティスは、データモデルを再構築することにより、循環参照を完全に回避することです。ただし、特にオブジェクト間の複雑な関係を扱う場合、これは必ずしも実行可能ではありません。
2。一意の識別子を使用**
効果的な戦略の1つは、一意の識別子または代理キーに置き換えることにより、円形の参照を破ることです。これには、各オブジェクトを一度シリアル化し、後続の発生に参照(IDなど)を使用することが含まれます。このアプローチにより、各オブジェクトが一度だけシリアル化され、データの複製が減少し、効率が向上することが保証されます。
3。json.net **の参照loophandling
json.netは、「referenceLoophandling」オプションを提供します。これは、「serialize」または「agnore」に設定できます。 「Serialize」オプションは、完全なオブジェクトグラフをシリアル化し、その後の発生の参照を使用して、複製なしで円形の参照を正確に保存します。 「無視」オプションは、円形の参照を除外することによりシリアル化を簡素化しますが、データの矛盾と複製をもたらす可能性があります。
4。json.net **のpreservereferenceshandling
Json.netは、「preservereferenceshandling」もサポートしており、各シリアル化されたオブジェクトに「$ id」プロパティを追加します。同じオブジェクトへの後続の参照は、元の「$ id」を指す `$ ref`プロパティとして表されます。この方法は、同じオブジェクトの冗長なシリアル化を回避することにより、循環参照を効率的に処理します。
###5。System.Text.jsonReferenceHandler **
.NETの `System.text.json`では、「ReferenceHandler」プロパティを使用してオブジェクト参照を保存できます。 「referenceHandler.preserve」に設定すると、json.netのアプローチと同様に、参照を追跡するためにメタデータを追加することにより、循環参照を処理できます。
6。カスタムシリアル化**
内蔵設定でカバーされていないシナリオの場合、カスタムコンバーターまたはハンドラーを作成できます。これには、参照を手動で追跡および解決するためのロジックを実装し、複雑または特定のユースケースに柔軟性を提供します。
7。円形の参照を無視**
円形の参照を保存する必要がない場合は、ジャクソンの「@jsonignore」などのアノテーションや他のライブラリの同様のメカニズムを使用して無視できます。このアプローチはシリアル化を簡素化しますが、データ表現が不完全につながる可能性があります。
##適切なアプローチの選択
メソッドの選択は、特定の要件とパフォーマンスの考慮事項に依存します。
- データの整合性:完全なオブジェクトグラフを保存することが重要な場合は、「参照」グラフのような手法を使用します。
- 効率:データサイズを最小限に抑え、重複を避けることが優先順位を回避する場合は、一意の識別子または参照を使用します。
- シンプルさ:循環参照が重要でない場合、それらを無視することは最も単純なソリューションかもしれません。
最終的に、円形の参照を処理するには、データの整合性、効率性、およびシンプルさの間のトレードオフを効果的に理解する必要があります。
引用:[1] https://github.com/dotnet/corefx/issues/40045
[2] https://www.linkedin.com/pulse/efficient wandling-circular-references-json-brake-power-power-power-power-power-power-power-power-power-power-power-power-power
[3] https://www.reddit.com/r/unity3d/comments/gjvv2n/json_serializing_of_recursive_class/
[4] https://infinum.com/handbook/dotnet/best-practics/json-serialization-and-deserialization
[5] https://softwareengineering.stackexchange.com/questions/229620/how-to-get-around-the-circular-reference-issue-with-json-and-entity
[6] https://stackoverflow.com/questions/10191671/jackson-json-serialization-recursion-avoidance-by-level-defining
[7] https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/preserve-references
[8] https://stackoverflow.com/questions/12584986/how-to-fix-circular-reference-error-when-dealing-with-json
[9] https://forums.servicestack.net/t/circular-references-in-jsonserializer-and-stackoverflow-exceptions/5725