16

私は Windows Azure テーブル ストレージを使用しており、単純な要件があります。新しい行を追加し、既存の行をその PartitionKey/RowKey で上書きします。ただし、ReplaceOnUpdate オプションを渡しても、変更を保存すると常に例外がスローされます。

tableServiceContext.AddObject(TableName, entity);
tableServiceContext.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate);

エンティティが既に存在する場合は、次をスローします。

System.Data.Services.Client.DataServiceRequestException: An error occurred while processing this request. ---> System.Data.Services.Client.DataServiceClientException: <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
  <code>EntityAlreadyExists</code>
  <message xml:lang="en-AU">The specified entity already exists.</message>
</error>

最初に既存の行を手動でクエリして呼び出す必要DeleteObjectがありますか? それは非常に遅いようです。きっともっと良い方法がありますか?

4

6 に答える 6

16

おわかりのように、同じ行キーとパーティション キーを持つ別の項目を追加することはできないため、クエリを実行して項目が既に存在するかどうかを確認する必要があります。このような状況では、Azure REST API のドキュメントを参照して、ストレージ クライアント ライブラリで何が利用できるかを確認すると役に立ちます。insertupdateには別々のメソッドがあることがわかります。ReplaceOnUpdateは、挿入時ではなく更新時にのみ効果があります。

既存のアイテムを削除してから新しいアイテムを追加することもできますが、既存のアイテムを更新することもできます (ストレージへの往復を 1 回節約できます)。コードは次のようになります。

var existsQuery = from e
                    in tableServiceContext.CreateQuery<MyEntity>(TableName)
                    where
                    e.PartitionKey == objectToUpsert.PartitionKey
                    && e.RowKey == objectToUpsert.RowKey
                    select e;

MyEntity existingObject = existsQuery.FirstOrDefault();

if (existingObject == null)
{
    tableServiceContext.AddObject(TableName, objectToUpsert);
}
else
{
    existingObject.Property1 = objectToUpsert.Property1;
    existingObject.Property2 = objectToUpsert.Property2;

    tableServiceContext.UpdateObject(existingObject);
}

tableServiceContext.SaveChangesWithRetries(SaveChangesOptions.ReplaceOnUpdate);

編集: 執筆時点では正しいですが、2011 年 9 月の更新により、Microsoft は Azure テーブル API を更新して、エンティティの挿入または置換とエンティティ挿入またはマージの 2 つの upsert コマンドを含めました。

于 2010-12-17T03:02:09.317 に答える
1

TableContextによって管理されていない既存のオブジェクトをDeleteまたはSaveChangeswithReplaceOnUpdateオプションで操作するには、TableContextに挿入を試みるように指示するAddObjectを呼び出す代わりに、AttachToを呼び出してオブジェクトをTableContextにアタッチする必要があります。

http://msdn.microsoft.com/en-us/library/system.data.services.client.dataservicecontext.attachto.aspx

于 2010-12-17T01:14:29.290 に答える
1

私の場合、最初に削除することは許可されていなかったので、このようにします。これにより、サーバーへの1つのトランザクションが発生し、最初に既存のオブジェクトが削除され、新しいオブジェクトが追加され、プロパティ値をコピーする必要がなくなります

       var existing = from e in _ServiceContext.AgentTable
                       where e.PartitionKey == item.PartitionKey
                             && e.RowKey == item.RowKey
                       select e;

        _ServiceContext.IgnoreResourceNotFoundException = true;
        var existingObject = existing.FirstOrDefault();

        if (existingObject != null)
        {
            _ServiceContext.DeleteObject(existingObject);
        }

        _ServiceContext.AddObject(AgentConfigTableServiceContext.AgetnConfigTableName, item);

        _ServiceContext.SaveChangesWithRetries();
        _ServiceContext.IgnoreResourceNotFoundException = false;
于 2010-12-29T14:41:09.077 に答える
1

Insert/Merge または Updateが 2011 年 9 月に API に追加されました。これは Storage API 2.0 を使用した例で、1.7 以前の API よりも理解しやすいものになっています。

public void InsertOrReplace(ITableEntity entity)
    {
        retryPolicy.ExecuteAction(
            () =>
            {
                try
                {
                    TableOperation operation = TableOperation.InsertOrReplace(entity);
                    cloudTable.Execute(operation);
                }
                catch (StorageException e)
                {
                    string message = "InsertOrReplace entity failed.";

                    if (e.RequestInformation.HttpStatusCode == 404)
                    {
                        message += " Make sure the table is created.";
                    }

                    // do something with message
                }
            });
    }
于 2013-03-29T18:31:16.030 に答える
0

ストレージ API では、グループ トランザクション内のエンティティ (削除 + 挿入) ごとに複数の操作を許可しません。

エンティティはトランザクションに 1 回だけ表示され、それに対して実行できる操作は 1 つだけです。

MSDN: エンティティ グループ トランザクションの実行を参照してください。

したがって、実際には、最初に読んで、挿入または更新を決定する必要があります。

于 2011-08-11T10:57:16.270 に答える