從零開始用C#做產品:私人日記(17)內容管理BAL最佳化

上一節我們開始內容管理的資料設計,這節我們來完成內容管理BAL部分的程式碼。

在實現Category的時候,增刪改的SQL語句基本上就是一段特定格式的字串,雖然可以自己做ORM工具來自動生成,但不是我們這個教程要講的。我們今天重點講下對查詢後結果的最佳化。

在Model。Categoty類中,我們資料轉換程式碼是這樣的:

從零開始用C#做產品:私人日記(17)內容管理BAL最佳化

事實上上面的程式碼是不夠安全的,比如:

model。Id =

int

Parse

(result[

“Id”

]。

ToString

());

result中未必包含Id的鍵值,結果就可能為空,轉換時就會出錯;

result中包含Id的鍵值,但可能不是數字,轉換時也會出錯;

一旦出錯,程式就爆掉了。

正確的程式碼應該加上上面兩種情況的判斷,外加呼叫int。TryParse的方法, 嘗試去轉換,但是這就不是一兩行程式碼就能搞定的了,一個欄位的處理可能就要4-5行。如果僅僅是Category還好,欄位不多,Content有12個欄位,還有DateTime這種型別,幾十行程式碼來處理這些就顯得過於臃腫了,所以我們需要進行程式碼最佳化。

上面的程式碼,共同之處都是從一個Hashtable的例項中獲取資料,不同的地方有兩點:一是返回型別,二是鍵值,有共性就可以用函式,有不同就傳引數,外加C#的一個專門用於工具類的擴充套件方法,就可以完美解決此問題。

在BAL中我聲明瞭一個靜態類BALTools,定義了對應Sqlite四種基本型別的函式:

namespace Diary。BAL{static public class BALTools{static public string toString(this Hashtable ht, string key, string dv = “”){if (ht == null) return dv;if (!ht。Contains(key)) return dv;if (ht[key] == null) return dv;return ht[key]。ToString();}static public int toInt(this Hashtable ht, string key, int dv=0){string str_v = ht。toString(key);if (string。IsNullOrEmpty(str_v)) return dv;int。TryParse(str_v, out dv);return dv;}static public DateTime toDateTime(this Hashtable ht, string key){DateTime dv = DateTime。MinValue;string str_v = ht。toString(key);if (string。IsNullOrEmpty(str_v)) return dv;DateTime。TryParse(str_v, out dv);return dv;}static public bool toBool(this Hashtable ht, string key, bool dv = false){string str_v = ht。toString(key);if (string。IsNullOrEmpty(str_v)) return dv;return str_v == “1”;}}}

這裡有兩個知識點:

第一個知識點擴充套件方法。

大家可能注意到了,每個函式的第一個引數:this+引數型別+引數名。這種在靜態類、靜態函式中,且第一個引數使用了this,編譯器就會為這個指定的引數型別創造出一個擴充套件方法。相當於你繼承了這個類,可以使用這些方法。

說起來可能比較難理解,看下動圖就很容易理解了:

從零開始用C#做產品:私人日記(17)內容管理BAL最佳化

我們可以看到,一個Hashtable的例項result,直接擁有了toInt、toString等方法,這種就叫擴充套件方法,設計好了就可以讓你節省大量重複性的程式碼。

第二個知識點是在函式引數中加預設值。

比如toString的最後一個引數是

string dv = “”

dv就是default value的縮寫,假設我在取值的這個鍵值不存在,那麼我就事先預設一個值,如果不存在,我就用這個預先設定的值來返回。在函式定義的時候設定了一個值是什麼意思呢?就是呼叫函式的時候我可以不指定這個值,預設使用函式定義的,只有在有必要更改這個預設值的時候,我才需要指定它。

result。toString(“Name”)result。toString(“Name”, “無標題”)

都是可以的。

做完上述的改進,我們開始編碼:

Category的查詢部分:

從零開始用C#做產品:私人日記(17)內容管理BAL最佳化

Content的查詢部分:

從零開始用C#做產品:私人日記(17)內容管理BAL最佳化

透過我們的最佳化,查詢部分程式碼的健壯性、可讀性都得到了很大的提升,而且以後再有其他的資料庫我們也都可以複用這幾個方法,這個工作非常值得。我們無論是做專案還是做產品,其實都要不斷地總結、最佳化,最終形成你自己的程式碼庫,設計更加合理,編碼更加高效。其實這也是我極力向大家推薦C#的原因之一,透過你的長期積累,能做的事情就越來越多,用C#是可以全棧開發的,也就是說,等你積累到了一定程度,你基本上可以優雅、高效的做任何你想做的事了,而且自己寫的類庫根本不用擔心版權問題,這是其他很多語言無可比擬的。

我在教程裡的內容都沒有用其他的類庫,然後有些人就各種噴,其實我現在寫這個系列教程就跟打網遊的開荒一樣,一切從零開始。噴子們開發只會用輪子,而我們這些獨立開發者是可以自己造輪子的。

DAL。Content的增刪改函式就沒什麼知識點可說的了,大家自行到Git上查閱程式碼。

底層工作準備好之後,我們下一節開始介面設計。

——————————————————————————

本教程儘量保證2天一更,專案原始碼已作為開源專案加入到Gitee,程式碼內容會隨教程實時更新,大家有興趣的話可以關注我,以獲得最及時的更新。私信:

私人日記

可以獲取Gitee的連結;

sqlitestudio

可以獲取sqlitestudio的連結;

菜鳥

可以獲取菜鳥教程連結;

大家閱讀過程中有哪些看不懂或未盡興的地方,可以在評論區留言,我會先記下來在後續的教程中找機會再說。

教程有幫助的話請大家幫忙關注、轉發、擴散,能不能開專欄還需要你們的支援!