2017-06-25 10 views
1

Azureテーブルストレージは、(int、string、Guid、DateTime)などの基本データタイプのみをサポートします。ネストされたオブジェクト。 List <>などのコレクションデータ型を直接格納することもサポートされていません。ネストされたオブジェクトとカスタムプロパティタイプをサポートするAzure TableのITableEntityインターフェイスの実装

このため、ITableEntityから継承し、新しく導入されたTableEntity.Flatten(...)およびTableEntity.ConvertBack<TResult>(...)メソッドを使用してReadEntityメソッドとWriteEntityメソッドを実装したCustomEntityクラスを作成しました。私は現在、入れ子になったオブジェクトの格納にのみ焦点を当てています。

public class CustomEntity : ITableEntity 
{ 
    // Partition Key, Row Key, Timestamp and ETag here 

    public void ReadEntity(IDictionary<string, EntityProperty> properties, OperationContext operationContext) 
    { 
     CustomEntity customEntity = TableEntity.ConvertBack<CustomEntity>(properties, operationContext); 
     // Do the memberwise clone for this object from the returned CustomEntity object 
     CloneThisObject(this, customEntity); 
    } 

    public IDictionary<string, EntityProperty> WriteEntity(OperationContext operationContext) 
    { 
     IDictionary<string, EntityProperty> flattenedProperties = TableEntity.Flatten(this, operationContext); 
     flattenedProperties.Remove("PartitionKey"); 
     flattenedProperties.Remove("RowKey"); 
     flattenedProperties.Remove("Timestamp"); 
     flattenedProperties.Remove("ETag"); 
     return flattenedProperties; 
    } 
} 

私のモデルで上記のコードを使用し、Azureテーブルにネストされたオブジェクトを正常に挿入できました。この問題は、同じオブジェクトを取得したいときに発生します。コードはtable.Execute(TableOperation.Retrieve(partitionKey, rowKey))コマンドで無限ループに陥ります。

また、CustomEntityオブジェクトの挿入操作中にWriteEntityコードがヒットしましたが、エンティティの取得中にReadEntityコードがヒットしませんでした。私はここで何が欠けていますか?どんな助けでも大歓迎です。

+1

あなたは問題の短い、完全な再版を投稿できますか? –

+1

キーバリューストアとして設計されたエンジンにドキュメントストアの種類を作成しようとしているのはなぜですか?なぜCosmosDBを使わないのですか?または、jsonドキュメントをテーブルストレージ列に格納するだけですか? –

+0

@ PeterBons価格、パフォーマンス、クエリパターン、バッチ処理などのテーブルストレージと階層オブジェクトを使用する理由はたくさんあります。 – Igorek

答えて

1

エンティティの取得中にReadEntityコードがヒットしません。

table.Execute(TableOperation.Retrieve(partitionKey、rowKey))メソッドは、DynamicTableEntityを返します。定義したReadEntityメソッドは呼び出されません。次のようなクエリを実行すると、ReadEntityメソッドがヒットします。

var entity = table.Execute(TableOperation.Retrieve<CustomEntity>(partitionKey, rowKey)).Result; 

ネストされたオブジェクトを持つエンティティを取得するのに役立つ一般的な方法を作成しました。以下のコードは参照用です。

public static List<T> GetEntities<T>(CloudTable table, string filter) where T : ITableEntity, new() 
{ 
    List<T> entities = new List<T>(); 

    DynamicTableEntity dynamicTableEntity = new DynamicTableEntity(); 

    dynamicTableEntity.Properties = TableEntity.Flatten(new T(), new OperationContext()); 

    TableQuery<DynamicTableEntity> projectionQuery = new TableQuery<DynamicTableEntity>().Where(filter); 
    foreach (var dEntity in table.ExecuteQuery(projectionQuery)) 
    { 
     T entity = EntityPropertyConverter.ConvertBack<T>(dEntity.Properties, new OperationContext()); 

     entity.PartitionKey = dEntity.PartitionKey; 
     entity.RowKey = dEntity.RowKey; 
     entity.ETag = dEntity.ETag; 
     entity.Timestamp = dEntity.Timestamp; 

     entities.Add(entity); 
    } 
    return entities; 
} 

ここにテストコードがあります。

ネストされたオブジェクトの定義。あなたの投稿に定義されているCustomEntityから継承します。

public class EmployeeEntity : CustomEntity 
{ 
    public EmployeeEntity(string lastName, string firstName) 
    { 
     this.PartitionKey = lastName; 
     this.RowKey = firstName; 
    } 

    public EmployeeEntity() { } 

    public string Email { get; set; } 

    public Address ContactAddress { get; set; } 
} 

public class Address 
{ 
    public string Province { get; set; } 

    public string City { get; set; } 
} 

テーブルの従業員エンティティを取得します。

CloudTable table = tableClient.GetTableReference("tableName"); 
var entities = CustomEntity.GetEntities<EmployeeEntity>(table, "PartitionKey eq 'pk'"); 
+1

更新はありますか?あなたは私の提案を試しましたか?ご不明な点がございましたら、お気軽にお知らせください。 – Amor

+0

ご協力いただきありがとうございます。私はRetrieve を使用してあなたの提案を試みました。そして、私はAzureテーブルからエンティティを正常に書き込んで読み込めました。しかし、FlattenとConvertBackのメソッドでもコレクションオブジェクトを使うことができないということを考えれば、私は自分のシリアル化、つまりデシリアライズロジックを作成しました。 –

+0

これは不要です。 'DynamicTableEntity dynamicTableEntity = new DynamicTableEntity();私は明示的な割り当ての必要がないことを覚えている限り、ConvertBackはPK、RK、ETag、Timestampを既に処理する必要があります。 –

関連する問題