自定義 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 是本文的主角,它代表了 Table 上的一個查詢。基本用法是使用查詢條件構建一個 TableQuery 類的例項,然後把這個例項作為引數傳遞給 CloudTable 的 ExecuteQuery 方法:
TableQuery query = new TableQuery().Where( TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "201607")); var queryResult = logTable.ExecuteQuery(query);
我們還可以使用 TableQuery 的靜態方法 CombineFilters 構建自定義的查詢條件。
比如我們要查詢 PartitionKey 等於 "201607" 並且 RowKey 等於"161148372454"的記錄:
TableQuery.CombineFilters( TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "201607"), TableOperators.And, TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, "161148372454"));
此時函式的返回結果為: ” (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 - 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);
- }
應用StartsWith的例項
現在查詢 PartitionKey 為”201607”,RowKey 以”16”開頭的記錄可以這麼寫:
StartsWithByRowKey myStartsWithQuery = new StartsWithByRowKey("201607", "16");
List result = myStartsWithQuery.Execute(logTable);
程式碼簡潔了很多,讀起來也更清晰了(您還可以動手給 PartitionKey 新增同樣的功能)!
小結一下,本文簡單的介紹了 TableQuery 型別,然後比較詳細的說明了 StartsWith 過濾條件的思路及實現。主要是想透過 StartsWith 的實現來說明如何利用現有的型別和方法來實現自定義查詢的過濾條件。對於有類似需求的朋友,希望能起到拋磚引玉的作用。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28298702/viewspace-2122845/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Azure 基礎:自定義 Table storage 查詢條件
- 34. 過濾條件、多表查詢、子查詢
- mysql多條件過濾查詢之mysq高階查詢MySql
- MySQL全面瓦解7:查詢的過濾條件MySql
- MongoDB之資料查詢(where條件過濾)MongoDB
- JN專案-查詢條件過濾特殊字元字元
- Azure Storage 系列(五)通過Azure.Cosmos.Table 類庫在.Net 上使用 Table Storage
- Azure 基礎:Table storage
- 關於 hibernate 邏輯刪除 預設查詢過濾條件問題(java set 條件)Java
- 條件過濾檢索
- MongoDB查詢條件MongoDB
- MongoDB條件查詢MongoDB
- mysql條件查詢MySql
- odoo 為可編輯列表檢視欄位搜尋新增查詢過濾條件Odoo
- Laravel 多條件查詢Laravel
- SQL多條件查詢SQL
- 條件查詢JSPJS
- django自定義 過濾器薦Django過濾器
- 4、過濾器的使用及自定義過濾器過濾器
- Elasticsearch——filter過濾查詢ElasticsearchFilter
- Elasticsearch 查詢與過濾Elasticsearch
- SpringBoot整合Jpa對資料進行排序、分頁、條件查詢和過濾Spring Boot排序
- 08.Django自定義模板,自定義標籤和自定義過濾器Django過濾器
- mongodb條件查詢不等於MongoDB
- golang beego orm 查詢條件 or andGolangORM
- 【mybatis-plus】條件查詢MyBatis
- 多條件查詢---ssh版本
- sql 查詢條件問題SQL
- 查詢條件封裝物件封裝物件
- Javaweb-DQL-條件查詢JavaWeb
- angular中的自定義過濾器Angular過濾器
- 詳解Django自定義過濾器Django過濾器
- django自定義過濾器例項Django過濾器
- 寫一個“特殊”的查詢構造器 – (四、條件查詢:複雜條件)
- sphinx查詢過濾問題
- dcat-admin表單值唯一驗證(帶自定義查詢條件使用舉例)
- mysql拆分字串做條件查詢MySql字串
- AntDesignBlazor示例——列表查詢條件Blazor