有個項目需要保存多個配置項蛔翅,配置項可能隨著開發(fā)不斷增加门驾。偏向使用SQLite數(shù)據(jù)庫配合ORM(對象關(guān)系映射)來實現(xiàn)。
因為要求并不復(fù)雜娃善,就打算自己簡單實現(xiàn)一下论衍,練下手。
這里記錄遇到的一些點聚磺。
類
- C#中的泛型類坯台,可以看作時針對某種泛型生成了新的類。比如類聲明的靜態(tài)代碼塊(靜態(tài)構(gòu)造函數(shù))
static ClassName(){}
會在使用新的泛型時重新執(zhí)行瘫寝。不同泛型蜒蕾,類的靜態(tài)變量也不互通。 - 類的
readonly
字段只能在聲明期間或構(gòu)造函數(shù)賦值(包括靜態(tài)構(gòu)造函數(shù)焕阿,當(dāng)然這種情況需要變量也是靜態(tài)的)咪啡。
反射
- 反射可通過
System.Type
對象實現(xiàn),Type
對象可由typeof(ClassName)
或obj.getType()
獲得暮屡。 - 類內(nèi)容的獲瘸访:
Type
對象有一系列Get()方法
,可以訪問類內(nèi)的屬性(即有get()
褒纲、set()
的變量)准夷、變量、方法等莺掠,返回值都是封裝好的對象或是對象集合衫嵌。 - 實例的創(chuàng)建,
Activator.CreateInstance()
:T t=Activator.CreateInstance<T>();
- 泛型實例屬性讀寫(
SetValue()
/GetValue()
):public void Increase(T t) { var propA = typeof(T).GetProperty("A"); var value = propA.GetValue(t, null); if (propA.PropertyType == typeof(int)) { var result = int.Parse(value.ToString()) + 1; propA.SetValue(t, result, null); } }
特性(注解)
- 通過繼承
System.Attribute
類即可彻秆。public class NonSQL : Attribute { } class Person { [NonSQL] public string FirstName {get;set;} }
- 想要獲取屬性的特性楔绞,可以通過
PropertyInfo.GetCustomAttributes()
即可獲取结闸,其他如字段等也有類似方法。
SQLite
- SQLite對
alter
的支持有限酒朵,字段一旦添加桦锄,就不能通過alter
語句修改字段的屬性(類型、主鍵等)耻讽。 - 查找表是否存在,(0-表名):
select count(*) from sqlite_master where type='table' and name = '{0}';
- 建表帕棉,(0-表名针肥;1-以逗號隔開的字段定義):
create table if not exists {0} ({1});
- 添加字段,(0-表名香伴;1-字段定義):
alter table {0} add column {1};
- 插入慰枕,(0-表名;1-以逗號隔開的字段即纲;2-以逗號隔開的字段對應(yīng)值):
insert or replace into {0} ({1}) values ({2});
-
where
子句使用:以and
連接多個條件具帮,除了邏輯運算符外,還可以使用like
做字符匹配低斋,百分號(%)代表零個蜂厅、一個或多個數(shù)字或字符,下劃線(_)代表一個單一的數(shù)字或字符膊畴,符號可被組合使用掘猿。 - 執(zhí)行查詢時會返回
SQLiteDataReader
對象,有很多方法唇跨,這里說兩個常用的稠通。- 通過
Read()
讀取一列數(shù)據(jù),讀取成功返回true买猖。 - 通過
["{PropName}"]
可以直接讀取字段的值改橘。
- 通過
- 兩種執(zhí)行語句的方法
// 只是執(zhí)行一條SQL語句 private void ExecuteNonQuery(string sql) { lock (connection) { EnsureDatabaseConnected(); using (var tr = connection.BeginTransaction()) { using (var command = connection.CreateCommand()) { command.CommandText = sql; command.ExecuteNonQuery(); } tr.Commit(); } } } // 執(zhí)行一條SQL語句,并執(zhí)行提供的操作玉控,一般用于查詢 private void ExecuteQuery(string sql, Action<SQLiteDataReader> action) { lock (connection) { EnsureDatabaseConnected(); using (var command = connection.CreateCommand()) { command.CommandText = sql; var reader = command.ExecuteReader(); action(reader); } } } //后一種的使用示例 public int GetTableCount(string tableName) { var tableCount = 0; var tableCountSql = string.Format("select count(*) from sqlite_master where type='table' and name = '{0}';", tableName); ExecuteQuery(tableCountSql, reader => { reader.Read(); tableCount = reader.GetInt32(0); }); return tableCount; }
其他
- 盡量使用泛型方法而不是泛型類飞主。
-
String.IsNullOrWhiteSpace()
,除了null
和空字符串(String.IsNullOrEmpty()
判斷范圍)高诺,還擴展了空白字符的判斷既棺。 - C#中有一個
System.IO.Path
類,可以很方便的拼接文件路徑懒叛、提取文件所在文件夾等丸冕。并且操作是跨平臺的。