有個項目需要保存多個配置項,配置項可能隨著開發不斷增加。偏向使用SQLite數據庫配合ORM(對象關系映射)來實現。
因為要求并不復雜,就打算自己簡單實現一下,練下手。
這里記錄遇到的一些點。
類
- C#中的泛型類,可以看作時針對某種泛型生成了新的類。比如類聲明的靜態代碼塊(靜態構造函數)
static ClassName(){}
會在使用新的泛型時重新執行。不同泛型,類的靜態變量也不互通。 - 類的
readonly
字段只能在聲明期間或構造函數賦值(包括靜態構造函數,當然這種情況需要變量也是靜態的)。
反射
- 反射可通過
System.Type
對象實現,Type
對象可由typeof(ClassName)
或obj.getType()
獲得。 - 類內容的獲取:
Type
對象有一系列Get()方法
,可以訪問類內的屬性(即有get()
、set()
的變量)、變量、方法等,返回值都是封裝好的對象或是對象集合。 - 實例的創建,
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-以逗號隔開的字段對應值):
insert or replace into {0} ({1}) values ({2});
-
where
子句使用:以and
連接多個條件,除了邏輯運算符外,還可以使用like
做字符匹配,百分號(%)代表零個、一個或多個數字或字符,下劃線(_)代表一個單一的數字或字符,符號可被組合使用。 - 執行查詢時會返回
SQLiteDataReader
對象,有很多方法,這里說兩個常用的。- 通過
Read()
讀取一列數據,讀取成功返回true。 - 通過
["{PropName}"]
可以直接讀取字段的值。
- 通過
- 兩種執行語句的方法
// 只是執行一條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(); } } } // 執行一條SQL語句,并執行提供的操作,一般用于查詢 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
類,可以很方便的拼接文件路徑、提取文件所在文件夾等。并且操作是跨平臺的。