如何在PartitionKey中使用单引号查询azure表存储

Yel*_*ive 8 c# urlencode azure azure-table-storage

我正在将一些代码从较旧的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();

    }
}
Run Code Online (Sandbox Code Playgroud)

我已经尝试了所有内容...我尝试显式设置TableQuery的FilterString属性,但它在设置该属性后执行URL编码,因此如果我用%27替换单引号,%得到双重转义.

有没有人有一个解决方法,允许我使用新的表存储库,而不回退到旧的StorageClient库?请注意,我在现有数据库中已经有很多数据,所以像"在查询中不使用单引号"这样的解决方案将是绝对的最后手段,因为它需要扫描和更新每个现有表中的每个记录. - 我想避免的维护任务.

San*_*tia 5

您需要转义单引号,但仅在过滤时(通过在原始单引号之前添加单引号):

string partitionFilter = TableQuery.GenerateFilterCondition("PartitionKey", 
          QueryComparisons.Equal, "what''s up");
Run Code Online (Sandbox Code Playgroud)

这是因为GenerateFilterConditionCombineFilters以简单的字符串(OData格式)转换过滤器:

(PartitionKey eq 'what''s up') and (RowKey eq 'blah')
Run Code Online (Sandbox Code Playgroud)

使用过滤器的更安全的方法是这样的:

string partitionFilter = TableQuery.GenerateFilterCondition("PartitionKey", 
          QueryComparisons.Equal, partitionKey.Replace("'", "''"));
Run Code Online (Sandbox Code Playgroud)