美文网首页
C#实现一个简单的SQLite ORM框架记录

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

作者: KwokKwok | 来源:发表于2018-08-08 23:05 被阅读194次

    有个项目需要保存多个配置项,配置项可能随着开发不断增加。偏向使用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类,可以很方便的拼接文件路径、提取文件所在文件夹等。并且操作是跨平台的。

    相关文章

      网友评论

          本文标题:C#实现一个简单的SQLite ORM框架记录

          本文链接:https://www.haomeiwen.com/subject/avlxbftx.html