C#实现一个简单的SQLite ORM框架记录

有个项目需要保存多个配置项,配置项可能随着开发不断增加。偏向使用SQLite数据库配合ORM(对象关系映射)来实现。

因为要求并不复杂,就打算自己简单实现一下,练下手。

这里记录遇到的一些点。

  1. C#中的泛型类,可以看作时针对某种泛型生成了新的类。比如类声明的静态代码块(静态构造函数static ClassName(){}会在使用新的泛型时重新执行。不同泛型,类的静态变量也不互通。
  2. 类的readonly字段只能在声明期间或构造函数赋值(包括静态构造函数,当然这种情况需要变量也是静态的)。

反射

  1. 反射可通过System.Type对象实现,Type对象可由typeof(ClassName)obj.getType()获得。
  2. 类内容的获取:Type对象有一系列Get()方法,可以访问类内的属性(即有get()set()的变量)、变量、方法等,返回值都是封装好的对象或是对象集合。
  3. 实例的创建,Activator.CreateInstance()
    T t=Activator.CreateInstance<T>();
    
  4. 泛型实例属性读写(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);
        }
    }
    

特性(注解)

  1. 通过继承System.Attribute类即可。
    public class NonSQL : Attribute
    {
    
    }
    
    class Person
    {
        [NonSQL]
        public string FirstName {get;set;}
    }
    
  2. 想要获取属性的特性,可以通过PropertyInfo.GetCustomAttributes()即可获取,其他如字段等也有类似方法。

SQLite

  1. SQLite对alter的支持有限,字段一旦添加,就不能通过alter语句修改字段的属性(类型、主键等)。
  2. 查找表是否存在,(0-表名):
    select count(*)  from sqlite_master where type='table' and name = '{0}';
    
  3. 建表,(0-表名;1-以逗号隔开的字段定义):
    create table if not exists {0} ({1});
    
  4. 添加字段,(0-表名;1-字段定义):
    alter table {0} add column {1};
    
  5. 插入,(0-表名;1-以逗号隔开的字段;2-以逗号隔开的字段对应值):
    insert or replace into {0} ({1}) values ({2});
    
  6. where子句使用:以and连接多个条件,除了逻辑运算符外,还可以使用like做字符匹配,百分号(%)代表零个、一个或多个数字或字符,下划线(_)代表一个单一的数字或字符,符号可被组合使用。
  7. 执行查询时会返回SQLiteDataReader对象,有很多方法,这里说两个常用的。
    1. 通过Read()读取一列数据,读取成功返回true。
    2. 通过["{PropName}"]可以直接读取字段的值。
  8. 两种执行语句的方法
    // 只是执行一条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;
    }
    

其他

  1. 尽量使用泛型方法而不是泛型类。
  2. String.IsNullOrWhiteSpace(),除了null和空字符串(String.IsNullOrEmpty()判断范围),还扩展了空白字符的判断。
  3. C#中有一个System.IO.Path类,可以很方便的拼接文件路径、提取文件所在文件夹等。并且操作是跨平台的。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,194评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,058评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,780评论 0 346
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,388评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,430评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,764评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,907评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,679评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,122评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,459评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,605评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,270评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,867评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,734评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,961评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,297评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,472评论 2 348

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,598评论 18 399
  • 大概是五天前,我发现鱼缸里有条鱼不再进食,不知是生了什么病,于是它越来越瘦,从刚开始的活泼也变得喜欢沉在水底...
    我们每个人都有理想阅读 223评论 0 0
  • 总结: 英语,对于阅读,主要的大原则是形成认知惯性,利用其快速阅读过去理解生词和生句 个人,真正地锻炼自己解决问题...
    车凯威RichardFeynm阅读 125评论 0 0
  • 本文适用于成都个人买社保,网上缴费。 网址 成都市社会保险网上经办系统 操作指南文档地址: 打开成都市社会保险网上...
    宁静的夜阅读 1,739评论 0 0
  • 时间没有重来,所以你要在最美的年华努力绽放最美的自己,别让遗憾成永远。
    红莲天舞阅读 135评论 0 0