yotiky Tech Blog

とあるエンジニアの備忘録

Azure Functions で Azure Table Storage を操作する

目次

検証環境

  • Azure Functions v3
  • Microsoft.Azure.Cosmos.Table v1.0.8

古いライブラリに注意

  • WindowsAzure.Storage は非推奨
  • Microsoft.Azure.CosmosDB.Table はまもなく非推奨

実装

NuGet でライブラリをインストールする。

using Microsoft.Azure.Cosmos.Table;

データ定義は、TableEntity を継承したクラスを作成する。 取得時にパラメータなしのコンストラクタが必要になる。

public class CustomerEntity : TableEntity
{
    public CustomerEntity() { }
    public CustomerEntity(string lastName, string firstName)
    {
        PartitionKey = lastName;
        RowKey = firstName;
    }

    public string Email { get; set; }
    public string PhoneNumber { get; set; }
}

CloudTableインスタンスを取得する。

var connectionString = "ConnectionString";
var tableName = "TableA";

var storageAccount = CloudStorageAccount.Parse(connectionString);
var tableClient = storageAccount.CreateCloudTableClient();
var cloudTalbe = tableClient.GetTableReference(tableName);

// なければ作成する
await cloudTalbe.CreateIfNotExistsAsync();

挿入

1件挿入する場合。

var entity = new CustomerEntity("Tanaka", "Taro")
{ 
    Email = "aaa", 
    PhoneNumber = "001"
};

await cloudTalbe.ExecuteAsync(TableOperation.InsertOrReplace(entity));

まとめて挿入する場合。

var entities = new[]
{
    new CustomerEntity("Tanaka", "Taro"){ Email = "aaa", PhoneNumber = "001"},
    new CustomerEntity("Tanaka", "Jiro"){ Email = "bbb", PhoneNumber = "002"},
};

var operation = new TableBatchOperation();
foreach (var entity in entities)
{
    operation.Add(TableOperation.InsertOrReplace(entity));
}

await cloudTalbe.ExecuteBatchAsync(operation);

取得

PartitionKeyとRowKeyを指定して1件取得する場合。

var entity = new CustomerEntity("Tanaka", "Taro")
{ 
    Email = "aaa", 
    PhoneNumber = "001"
};

var tableResult = await cloudTalbe.ExecuteAsync(TableOperation.Retrieve<CustomerEntity>(entity.PartitionKey, entity.RowKey));
var result = tableResult.Result as CustomerEntity;

クエリを使う場合。

var entity = new CustomerEntity("Tanaka", "Taro")
{ 
    Email = "aaa", 
    PhoneNumber = "001"
};

var query = new TableQuery<CustomerEntity>();
query.FilterString =
    TableQuery.CombineFilters(
        TableQuery.GenerateFilterCondition(nameof(CustomerEntity.PartitionKey), QueryComparisons.Equal, entity.PartitionKey),
        TableOperators.And,
        TableQuery.GenerateFilterCondition(nameof(CustomerEntity.RowKey), QueryComparisons.Equal, entity.RowKey)
    );

var tableResult = await cloudTalbe.ExecuteQuerySegmentedAsync(query, null);

var result = tableResult.Results.SingleOrDefault();

大量に取得する場合。

var entity = new CustomerEntity("Tanaka", "Taro")
{ 
    Email = "aaa", 
    PhoneNumber = "001"
};

var query = new TableQuery<CustomerEntity>();
query.FilterString = 
    TableQuery.GenerateFilterCondition(nameof(CustomerEntity.PartitionKey), QueryComparisons.Equal, entity.PartitionKey);

var list = new List<CustomerEntity>();

TableContinuationToken token = null;
do
{
    var segment = await cloudTalbe.ExecuteQuerySegmentedAsync(query, token);
    list.AddRange(segment.Results);
    token = segment.ContinuationToken;
} while (token != null);

参考:1 件のクエリで大量のエンティティを取得する

削除

取得時の Entity が書き換わってないかチェックして削除する場合。

await cloudTalbe.ExecuteAsync(TableOperation.Delete(entity));

気にせず削除する場合は ETag にワイルドカードを使う。

var entity = new CustomerEntity("Tanaka", "Taro");
entity.ETag = "*";
await cloudTalbe.ExecuteAsync(TableOperation.Delete(entity));

参考

関連記事