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

时间:2012-11-28 23:31:51

标签: c# azure urlencode 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();

    }
}

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

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

2 个答案:

答案 0 :(得分:5)

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

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

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

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

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

string partitionFilter = TableQuery.GenerateFilterCondition("PartitionKey", 
          QueryComparisons.Equal, partitionKey.Replace("'", "''"));

答案 1 :(得分:1)

我正在使用Windows Azure Storage 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属性,则可以看到单引号已被转义:

  

&#34;(PartitionKey eq&#39; what&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#39;&#34;