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

C# 如何在PartitionKey中使用单引号查询azure表存储,c#,azure,urlencode,azure-table-storage,C#,Azure,Urlencode,Azure Table Storage,我正在将一些代码从较旧的azure table storage client迁移到最新版本,并遇到了一个让我困惑的问题:我似乎无法在分区键中发送带有单个引号的查询,而不会收到400个错误的请求。例如: public class TestEntity : TableEntity { public string TestProperty { get; set; } } public class StorageTester { public static void TestInser

我正在将一些代码从较旧的azure table storage client迁移到最新版本,并遇到了一个让我困惑的问题:我似乎无法在分区键中发送带有单个引号的查询,而不会收到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();

    }
}
公共类测试实体:TableEntity
{
公共字符串TestProperty{get;set;}
}
公共类存储测试器
{
公共静态void TestInsert()
{
CloudStorageAccount acct=CloudStorageAccount.DevelopmentStorageAccount;
CloudTableClient=acct.CreateCloudTableClient();
CloudTable=client.GetTableReference(“testtable”);
table.CreateIfNotExists();
//插入一个测试实体——这很好
TestEntity实体=新的TestEntity();
entity.PartitionKey=“怎么了”;
entity.RowKey=“blah”;
entity.TestProperty=“some dataz”;
TableOperation op=TableOperation.Insert(实体);
表.执行(op);
//现在查询实体——为清晰起见构造的显式查询
string partitionFilter=TableQuery.GenerateFilterCondition(“PartitionKey”,QueryComparisons.Equal,“what's up”);
字符串rowFilter=TableQuery.GenerateFilterCondition(“RowKey”,QueryComparisons.Equal,“blah”);
string finalFilter=TableQuery.CombineFilters(partitionFilter、TableOperators.And、rowFilter);
TableQuery=新建TableQuery()。其中(finalFilter);
//这会引发400错误,无法正确编码分区键
var entities=table.ExecuteQuery(查询,新TableRequestOptions{RetryPolicy=new NoRetry()});
实体=实体。FirstOrDefault();
}
}
我什么都试过了。。。我尝试显式设置TableQuery的FilterString属性,但它在设置该属性后执行URL编码,因此如果我将单引号替换为%27,则%将得到双转义


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

您需要避开单引号,但仅在筛选时(通过在原始单引号之前添加单引号):

这是因为
GenerateFilterCondition
CombineFilters
以简单字符串(OData格式)打开过滤器:

使用过滤器的更安全方法如下:

string partitionFilter = TableQuery.GenerateFilterCondition("PartitionKey", 
          QueryComparisons.Equal, partitionKey.Replace("'", "''"));
我正在使用,您可以使用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();
//获取cloudtable。。。
var table=GetCloudTable();
//创建查询:在本例中,我使用DynamicTableEntity类
var query=cloudTable.CreateQuery()
。其中(d=>d.PartitionKey==“怎么了”&&d.RowKey==“诸如此类”);
var entities=query.ToList();
如果检查
query.FilterString
属性,可以看到单引号已转义:

“(PartitionKey eq‘怎么了’)和(RowKey eq‘废话’)”


谢谢,这就是我要找的!实际上,我只是通过使用旧的StorageClient并查看开发人员的存储日志来了解它将为同一个查询生成什么url,从而解决了这个问题。不过,我很确定TableQuery代码应该自动处理这个问题。例如,InsertOrReplace table操作在分区键中只有一个引号的实体上失败——在使用该操作之前,您可能需要手动更改实体上的分区键。我将查看是否可以找到合适的位置将此作为错误报告提交给MS。此答案的更新,因为Windows Azure Storage 2.1,您不需要在查询中转义单个引号。图书馆会做的。更改日志如下:
string partitionFilter = TableQuery.GenerateFilterCondition("PartitionKey", 
          QueryComparisons.Equal, partitionKey.Replace("'", "''"));
// 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();