8

一部のコードを古いazureテーブルストレージクライアントから最新リリースに移行していますが、困惑する問題が発生しました。400の不正な要求を取得せずに、パーティションキーに一重引用符を含むクエリを送信できないようです。例えば:

public class TestEntity : TableEntity
{
    public string TestProperty { get; set; }
}

public class StorageTester
{
    public static void TestInsert()
    {
        CloudStorageAccount acct = CloudStorageAccount.DevelopmentStorageAccount;
        CloudTableClient client = acct.CreateCloudTableClient();
        CloudTable table = client.GetTableReference("testtable");
        table.CreateIfNotExists();

        // insert a test entity -- this works fine
        TestEntity entity = new TestEntity();
        entity.PartitionKey = "what's up";
        entity.RowKey = "blah";
        entity.TestProperty = "some dataz";

        TableOperation op = TableOperation.Insert(entity);
        table.Execute(op);

        // now query the entity -- explicit query constructed for clarity
        string partitionFilter = TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "what's up");
        string rowFilter = TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, "blah");
        string finalFilter = TableQuery.CombineFilters(partitionFilter, TableOperators.And, rowFilter);

        TableQuery<TestEntity> query = new TableQuery<TestEntity>().Where(finalFilter);

        // THIS THROWS 400 ERROR, does not properly encode partition key
        var entities = table.ExecuteQuery(query, new TableRequestOptions { RetryPolicy = new NoRetry() });
        entity = entities.FirstOrDefault();

    }
}

すべてを試しました...TableQueryのFilterStringプロパティを明示的に設定しようとしましたが、そのプロパティを設定した後にURLエンコードが実行されるため、一重引用符を%27に置き換えると、%は二重にエスケープされます。

古いStorageClientライブラリにフォールバックせずに新しいテーブルストレージライブラリを使用できるようにする回避策はありますか?既存のデータベースにはすでに多くのデータがあることに注意してください。「クエリで一重引用符を使用しない」などのソリューションは、既存のすべてのテーブルのすべてのレコードをスキャンして更新する必要があるため、絶対的な最後の手段になります。 -避けたいメンテナンス作業。

4

2 に答える 2

5

一重引用符をエスケープする必要がありますが、フィルタリングする場合に限ります(元の一重引用符の前に一重引用符を追加することにより)。

string partitionFilter = TableQuery.GenerateFilterCondition("PartitionKey", 
          QueryComparisons.Equal, "what''s up");

これは、フィルターを単純な文字列(OData形式)で変換するためGenerateFilterConditionですCombineFilters

(PartitionKey eq 'what''s up') and (RowKey eq 'blah')

フィルタを使用するより安全な方法は次のようになります。

string partitionFilter = TableQuery.GenerateFilterCondition("PartitionKey", 
          QueryComparisons.Equal, partitionKey.Replace("'", "''"));
于 2012-11-29T00:06:12.660 に答える
2

私はWindowsAzureStorage 7.0.0を使用していますが、Linqクエリを使用できるため、一重引用符をエスケープする必要はありません。

// Get the cloudtable ...
var table = GetCloudTable();

// Create a query: in this example I use the DynamicTableEntity class
var query = cloudTable.CreateQuery<TestEntity>()
    .Where(d => d.PartitionKey == "what's up" && d.RowKey == "blah");

var entities = query.ToList();

プロパティを調べるquery.FilterStringと、一重引用符がエスケープされていることがわかります。

"(PartitionKey eq'what''s up')and(RowKey eq'blah')"

于 2016-04-10T23:20:18.310 に答える