string startStr = "abc"; int endIndex = startStr.Length - 1; Char lastChar = startStr[endIndex]; // 找到比字符'c'大的那个字符。 Char afterLastChar = (char)(lastChar + 1); // 拼出字符串 "abd" string endStr = startStr.Substring(0, endIndex) + afterLastChar; string startsWithCondition = TableQuery.CombineFilters( TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.GreaterThanOrEqual, startStr), TableOperators.And, TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.LessThan, endStr) );
组合更多过滤条件在前面构建 StartsWith 过滤条件时我们已经使用 TableQuery.CombineFilters 方法组合了不同的过滤条件。遗憾的是 TableQuery.CombineFilters 方法只有两个参数的重载,我们不能添加更多的 TableOperators 操作。
但我们可以继续调用 TableQuery.CombineFilters 方法去组合上一个结果和新的条件。比如我们要把 Startswith 过滤条件和 PartitionKey 过滤条件组合起来就可以这么干:
string filterCondition = TableQuery.CombineFilters( TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "201607"), TableOperators.And, "(RowKey ge 'abc') and (RowKey lt 'abd')" );
运行上面的代码,生成的结果为:
(PartitionKey eq '201607') and ((RowKey ge 'abc') and (RowKey lt 'abd'))
到这来就很清楚了,TableQuery.CombineFilters 方法的主要工作就是把过滤条件组织成查询引擎能够识别的字符串。因而我们可以通过不断的叠加生成很复杂的过滤条件。
封装 StartsWith 过滤条件下面我们把 StartsWith 的逻辑封装到 StartsWithByRowKey 类型中,下面是完整的代码:
public class MyLogEntity : TableEntity
{
public MyLogEntity() { }
public MyLogEntity(string pkey, string rkey)
{
this.PartitionKey = pkey;
this.RowKey = rkey;
}
public DateTime LogDate { get; set; }
public string LogMessage { get; set; }
public string ErrorType { get; set; }
}
public class StartsWithByRowKey : IQuery<CloudTable, List<MyLogEntity>>
{
private readonly string partitionKey;
private readonly string startsWithString;
internal StartsWithByRowKey(string partitionKey,
string startsWithString)
{
this.partitionKey = partitionKey;
this.startsWithString = startsWithString;
}
public List<MyLogEntity> Execute(CloudTable coludTable)
{
var query = new TableQuery<MyLogEntity>();
int endIndex = startsWithString.Length - 1;
Char lastChar = startsWithString[endIndex];
Char afterLastChar = (char)(lastChar + 1);
string endStr = startsWithString.Substring(0, endIndex) + afterLastChar;
string startsWithCondition = TableQuery.CombineFilters(
TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.GreaterThanOrEqual, startsWithString),
TableOperators.And,
TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.LessThan, endStr)
);
string filterCondition = TableQuery.CombineFilters(
TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, partitionKey),
TableOperators.And,
startsWithCondition
);
var entities = coludTable.ExecuteQuery(query.Where(filterCondition));
return entities.ToList();
}
}
public interface IQuery<in TModel, out TResult>
{
TResult Execute(TModel model);
}
现在查询 PartitionKey 为"201607",RowKey 以"16"开头的记录可以这么写: