Microsoft.Azure.Documents.Document
オブジェクトをクラスタイプにキャストする方法はありますか?
CosmosDBTrigger
を使用してAzureFunctionクラスを作成しました。トリガーはMicrosoft.Azure.Documents.Document
の配列を受け取ります。レコード自体に関するメタデータにアクセスできるように、そのDocument
クラスを使用するのが好きですが、クラスタイプのデータを静的な方法で操作したいと思います。
ToString
を呼び出すと、データのJSON表現が表示されます。 Newtonsoftを使用してそのJSONをクラスタイプに手動で変換する必要がありますか?
関数でDocument
をPOCOにマップする必要がある場合、それを行う最も簡単な方法は、提案した方法です。
document.Resource.ToString()
メソッドを呼び出し、JSON.NETまたはお好みのjsonライブラリからDeserializeObject
を使用します。ただし、MicrosoftのCosmosDBライブラリでもJSON.NETを使用しているため、JSON.NETをお勧めします。
マッピング呼び出しは次のようになります。
var yourPoco = JsonConvert.DeserializeObject<YourPocoType>(document.Resource.ToString())
Nick Chapsasが提供するソリューションは機能しますが、より良いオプションをいくつか提供したいと思います。
まず、追加のメタフィールドに関心がある場合は、いつでも選択したプロパティをデータアクセスモデルに含めると入力できます。例:
public class Model
{
public String id { get; set; }
public String _etag { get; set; }
//etc.
}
次に、既存のAPIを使用して、明示的ですべての人に馴染みのあるものを逆シリアル化できます。例えば:
var explicitResult = await client.ReadDocumentAsync<Model>(documentUri);
Model explicitModel = explicitResult.Document;
次のレイヤーモデル(例:ドメインモデル)にこれらのストレージ固有のメタフィールドを持たせたくない場合は、別のモデルに変換する必要がありますが、それはcosmosDBレベルの問題ではなくなり、変換する汎用マッパーがたくさんありますPOCO間。
これは、強く型付けされたドキュメントモデルで作業する場合に、cosmosDBでデータアクセスを処理するためのIMHOの最もクリーンで推奨される方法です。
もう1つのトリックは、中間のキャストステップとしてダイナミックを使用することです。これはある意味で短くエレガントですが、個人的にダイナミックを使用すると常に少し汚く感じます。
var documentResult = await client.ReadDocumentAsync(documentUri);
Model dynamicModel = (dynamic)documentResult.Resource;
JObject
を読むもう1つの方法は、ドキュメントをNewtonSoftのJObject
として読み取ることです。これにはすべてのメタフィールドも含まれ、文字列表現間で余分なホッピングをすることなく、自分でさらにキャストすることができます。例:
var jObjectResult = await client.ReadDocumentAsync<JObject>(documentUri);
Model JObjectResult = jObjectResult.Document.ToObject<Model>();
Document
+ JObject
モデル内のドキュメントレベルのメタフィールドを本当に避けてアクセスしたい場合は、ちょっとしたリフレクショントリックを使用してJObject
インスタンスからDocument
を取得できます。
var documentResult = await client.ReadDocumentAsync(documentUri);
Document documentModel = documentResult.Resource;
var propertyBagMember = documentResult.Resource.GetType()
.GetField("propertyBag", BindingFlags.NonPublic| BindingFlags.Instance);
Model reflectionModel = ((JObject)propertyBagMember.GetValue(documentResult.Resource))
.ToObject<Model>();
リフレクショントリックは内部実装の詳細に依存しており、ライブラリ作成者による下位互換性の保証の対象ではないことに注意してください。