Azure 基础:自定义 Table storage 查询条件
本文是在 《Azure 基础:Table storage》 一文的基础上介绍如何自定义 Azure Table storage 的查询过滤条件。如果您还不太清楚 Azure Table storage 的基本用法,请先移步前文。
让我们回到前文中提到的一个问题,如何过滤出 MyLogTable 表中某一天产生的所有日志?在进入细节前我们先来回顾一下 MyLogTable 类的设计:
internal class MyLogEntity : TableEntity
{
public MyLogEntity() { }
public MyLogEntity(string pkey, string rkey)
{
this.PartitionKey = pkey;
this.RowKey = rkey;
}
//…
}
PartitionKey 用来存放产生日志的年份和月份(例如201607表示2016年7月),RowKey 用来存放产生日志的天和时分秒毫秒(例如160934248492表示16号9点34分…)。在我们设计的 MyLogTable 中,天信息保存在 RowKey 的前两位。我们要做的就是过滤 RowKey 的前两位,也就是找到所有 RowKey 以"xx"开头的记录。这在字符串操作中称为 StartsWith。遗憾的是现有 Table storage 的接口中没有提供这种功能的方法,因此我们需要自己实现它(还好 TableQuery 的实现支持我们去扩展它)!本文将通过实现 StartsWith 过滤条件说明如何自定义 Azure Table storage 的查询过滤条件。
TableQuery 类
TableQuery 是本文的主角,它代表了某个表上的一个查询。基本用法是使用查询条件构建一个 TableQuery 类的实例,然后把这个实例作为参数传递给 CloudTable 的ExecuteQuery 方法:
TableQuery<MyLogEntity> query = new TableQuery<MyLogEntity>().Where(
TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "")
);
var queryResult = logTable.ExecuteQuery(query);
我们还可以使用 TableQuery 的静态方法 CombineFilters 构建自定义的查询条件。比如我们要查询 PartitionKey 等于 "201607" 并且 RowKey 等于"161148372454"的记录:
TableQuery.CombineFilters(
TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, ""),
TableOperators.And,
TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, "")
);
此时函数的返回结果为: "(PartitionKey eq '201607') and (RowKey eq '161148372454')"。
然后把这个过滤字符串送给 query.Where 函数做参数,或者设置给 query.FilterString 属性,就可以完成过滤功能了。
CombineFilters 方法可爱的地方在于我们可以不断的用它来合并查询条件,直到满意为止!
接下来我们一起看看 StartsWith 过滤条件的实现过程。
比较字符串
如何从一些字符串中找出以某个子串开头的字符串呢?我们可以从字符串的比较入手。
比如字符串具有下面的关系:
“abc” == “abc” < “abd”
“abc” < “abca” < “abd”
“abc” < “abcz” < “abd”
由上面的大小关系我们可以得出结论:以"abc"开头的字符串必定大于或等于"abc"且小于"abd"。OK,这就是我们构建 StartsWith 过滤条件的理论基础。
构建 StartsWith 过滤条件
接下来我们通过 TableQuery.CombineFilters 方法构建 StartsWith 过滤条件:
string startsWithCondition = TableQuery.CombineFilters(
TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.GreaterThanOrEqual, "abc"),
TableOperators.And,
TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.LessThan, "abd")
);
TableQuery.CombineFilters 方法的返回值是一个字符串。运行上面的代码我们会得到字符串:
"(RowKey ge 'abc') and (RowKey lt 'abd')"
我们完全可以手动拼出这样的字符串,但我相信没有程序猿愿意这么干。所以我们要继续完善上面的方法:
string startStr = "abc";
int endIndex = startStr.Length - ;
Char lastChar = startStr[endIndex];
// 找到比字符'c'大的那个字符。
Char afterLastChar = (char)(lastChar + );
// 拼出字符串 "abd"
string endStr = startStr.Substring(, 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, ""),
TableOperators.And,
"(RowKey ge 'abc') and (RowKey lt 'abd')"
);
运行上面的代码,生成的结果为:
(PartitionKey eq '') 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 - ;
Char lastChar = startsWithString[endIndex];
Char afterLastChar = (char)(lastChar + );
string endStr = startsWithString.Substring(, 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);
}
应用 StartsWith 的实例
现在查询 PartitionKey 为"201607",RowKey 以"16"开头的记录可以这么写:
StartsWithByRowKey myStartsWithQuery = new StartsWithByRowKey("", "");
List<MyLogEntity> result = myStartsWithQuery.Execute(logTable);
代码简洁了很多,读起来也更清晰了(您还可以动手给 PartitionKey 也添加同样的功能)!
总结
本文简单的介绍了 TableQuery 类型,然后比较详细的说明了 StartsWith 过滤条件的思路及实现。主要是想通过 StartsWith 的实现来说明如何利用现有的类型及方法来实现自定义查询的过滤条件。对于有类似需求的朋友,希望能起到抛砖引玉的作用。
Azure 基础:自定义 Table storage 查询条件的更多相关文章
- Azure 基础:Table storage
Azure Storage 是微软 Azure 云提供的云端存储解决方案,当前支持的存储类型有 Blob.Queue.File 和 Table.其中的 Table 就是本文的主角 Azure Tabl ...
- Azure 基础:Blob Storage
Azure Storage 是微软 Azure 云提供的云端存储解决方案,当前支持的存储类型有 Blob.Queue.File 和 Table. 笔者在前文中介绍了 Table Storage 的基本 ...
- 自定义 Azure Table storage 查询过滤条件
本文是在Azure Table storage 基本用法一文的基础上,介绍如何自定义 Azure Table storage 的查询过滤条件.如果您还不太清楚 Azure Table storage ...
- Azure 基础:Queue Storage
Azure Storage 是微软 Azure 云提供的云端存储解决方案,当前支持的存储类型有 Blob.Queue.File 和 Table. 笔者在前文中介绍了 File Storage 的基本用 ...
- Azure 基础:File Storage
Azure Storage 是微软 Azure 云提供的云端存储解决方案,当前支持的存储类型有 Blob.Queue.File 和 Table. 笔者在前文中介绍了 Blob Storage 的基本用 ...
- JEECG中datagrid方法自定义查询条件
自定义加添加查询条件的用法: CriteriaQuery cq = new CriteriaQuery(EquipmentEntity.class, dataGrid); //查询条件组装器 org. ...
- Windows Azure Table Storage 解决 Guid 查询问题
在使用 Windows Azure Table Storage 的 CloudTableClient 对Azure 进行数据查询时,会发现在自定义类的Guid类型始终无法去成功查询出数据,对比发现 G ...
- Azure Storage 系列(四)在.Net 上使用Table Storage
一,引言 今天我们就不多说废话了,直接进入正题,Azure Table Storage.开始内容之前,我们先介绍一下Azure Table Storage. 1,什么是Azure Table Stor ...
- Azure Table storage 基本用法 -- Azure Storage 之 Table
Azure Storage 是微软 Azure 云提供的云端存储解决方案,当前支持的存储类型有 Blob.Queue.File 和 Table,其中的 Table 就是本文的主角 Azure Tabl ...
随机推荐
- Huawei DHCP 中继配置实例
配置DHCP中继示例 组网需求 如图1,DHCP客户端所在的网段为10.100.0.0/16,而DHCP服务器所在的网段为202.40.0.0/16.需要通过带DHCP中继功能的设备中继DHCP报文, ...
- TMOUT优化终端超时
有时候,管理员终端登陆了系统,如果离开没有退出账户,则会有安全隐患存在,因此需要优化终端超时. 设置终端超时: export TMOUT=10 永久生效: echo "export TMOU ...
- linux开机步骤
linux开机启动步骤: 1.bios自检 2.MBR引导 3.引导系统,进入grub菜单 4.加载内核kernel 5.运行第一个进程init 6.读取/etc/inittab 读取运行级别 7.读 ...
- PHP中unset,array_splice删除数组中元素的区别
php中删除数组元素是非常的简单的,但有时删除数组需要对索引进行一些排序要求我们会使用到相关的函数,这里我们来介绍使用unset,array_splice删除数组中的元素区别吧 如果要在某个数组中删除 ...
- RSA 非对称加密,私钥转码为pkcs8 错误总结
RSA 非对称加密,私钥转码为pkcs8 错误总结 最近在和某上市公司对接金融方面的业务时,关于RSA对接过程中遇到了一个坑,特来分享下解决方案. 该上市公司简称为A公司,我们简称为B公司.A-B两家 ...
- C# 颜色对照表
参考资料 :https://www.cnblogs.com/msgarden/p/4949272.html Color.AliceBlue 240,248,255 Color.LightSalmon ...
- Javaweb学习(三):Servlet程序
好了,既然开发环境已经配置好了.那么我们首先要搞定得便是servlet了,至于为什么不先去研究jsp,这是因为jsp与servlet本就是一体两面,jsp其本身经过编译.载入.转化等步骤最终会成为se ...
- 【转】为什么Github没有记录你的Contributions
【转】为什么Github没有记录你的Contributions 字数985 阅读0 评论0 喜欢0 记录下为什么github 提交的时候,没有记录到 github 的那个日历上。 Paste_Imag ...
- Springboot整合log4j2日志全解
目录 常用日志框架 日志门面slf4j 为什么选用log4j2 整合步骤 引入Jar包 配置文件 配置文件模版 配置参数简介 Log4j2配置详解 简单使用 使用lombok工具简化创建Logger类 ...
- 2.Linux环境下配置Solr4.10.3
转载请出自出处:http://www.cnblogs.com/hd3013779515/ 1.准备阶段 操作系统:CentOS 6.8 安装包:/home/test solr-4.10.3.tgz.t ...