【C#】使用ADO.NET/Dapper访问Sqlite数据库,SqliteHelper帮助类

1. 使用ADO.NET

这个就比较简单了,用过sqlserver的人都知道访问数据库的时候一般都会有个SqlHelper的帮助类,这里就依葫芦画瓢写了个SqliteHelper,很简单:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Thumbnail
{
    public class SqliteHelper
    {
        string dbPath = "E:\\thumbnail.db";
        string conStr = "Data Source=E:\\thumbnail.db";
        static SqliteHelper _instance;
        public static SqliteHelper Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new SqliteHelper();
                return _instance;
            }
        }

        string cmdCreateTable = "CREATE TABLE IF NOT EXISTS Thumbnails (Id integer PRIMARY KEY, OrginFilePath nvarchar NOT NULL UNIQUE, ThumbnailPath nvarchar NOT NULL,LastUpdateTime datetime NOT NULL);";
        string createIndex = "create index if not exists originIndex on Thumbnails (OrginFilePath)";
        private SqliteHelper() { }
        
        //如果需要初始化数据库可调用此方法
        public void Init()
        {
            if (!File.Exists(dbPath))
            {
	            //如果数据库文件不存在,则创建
                SQLiteConnection.CreateFile(dbPath);
            }
            List<TransModel> models = new List<TransModel>();
            models.Add(new TransModel { CmdText = cmdCreateTable });
            models.Add(new TransModel { CmdText = createIndex });
            bool res = ExecTransaction(models);//一个事务:如果表不存在则创建,如果索引不存在则创建
        }
        //执行非查询的sql语句,返回受影响的行数
        public int ExecuteNonQuery(string cmdText, params SQLiteParameter[] paramters)
        {
            using (SQLiteConnection con = new SQLiteConnection(conStr))
            {
                try
                {
                    con.Open();
                    using (SQLiteCommand cmd = new SQLiteCommand(con))
                    {
                        cmd.CommandText = cmdText;
                        if (paramters != null)
                            cmd.Parameters.AddRange(paramters);
                        return cmd.ExecuteNonQuery();
                    }
                }
                catch (SQLiteException ex)
                {
                    //_log.E(ex);
                }
                return -1;
            }
        }
        //执行非查询的sql语句,返回第一行第一列的值
        public object ExecuteScalar(string cmdText, params SQLiteParameter[] parameters)
        {
            using (SQLiteConnection conn = new SQLiteConnection(conStr))
            {
                try
                {
                    conn.Open();
                    using (SQLiteCommand cmd = new SQLiteCommand(conn))
                    {
                        cmd.CommandText = cmdText;
                        cmd.Parameters.AddRange(parameters);
                        return cmd.ExecuteScalar();
                    }
                }
                catch (SQLiteException ex)
                {
                    //_log.E(ex);
                }
                return null;
            }
        }
        //执行查询语句,返回查询到的结果
        public DataTable GetDataTable(string cmdText, params SQLiteParameter[] parameters)
        {
            using (SQLiteConnection conn = new SQLiteConnection(conStr))
            {
                try
                {
                    conn.Open();
                    using (SQLiteCommand cmd = new SQLiteCommand(conn))
                    {
                        DataTable dt = new DataTable();
                        cmd.CommandText = cmdText;
                        cmd.Parameters.AddRange(parameters);
                        SQLiteDataAdapter da = new SQLiteDataAdapter(cmd);
                        da.Fill(dt);
                        return dt;
                    }
                }
                catch (SQLiteException ex)
                {
                    //_log.E(ex);

                }
                return null;
            }
        }
        //执行事务,如果出现异常则回滚
        public bool ExecTransaction(List<TransModel> models)
        {
            using (SQLiteConnection con = new SQLiteConnection(conStr))
            {
                try
                {
                    con.Open();
                    using (SQLiteTransaction trans = con.BeginTransaction())
                    {
                        using (SQLiteCommand cmd = new SQLiteCommand(con))
                        {
                            cmd.Transaction = trans;
                            try
                            {
                                foreach (var model in models)
                                {
                                    cmd.CommandText = model.CmdText;
                                    if (model.Paras != null)
                                        cmd.Parameters.AddRange(model.Paras);
                                    cmd.ExecuteNonQuery();
                                }
                                trans.Commit();
                                return true;
                            }
                            catch (SQLiteException ex)
                            {
                                trans.Rollback();
                                //_log.E(ex);
                            }

                        }
                    }

                }
                catch (SQLiteException ex)
                {
                   // _log.E(ex);
                }
            }
            return false;
        }
    }
    public class TransModel
    {
        public string CmdText { get; set; }
        public SQLiteParameter[] Paras { get; set; }
    }
}

这里有几点需要注意,所有之前的SqlConnection都换成SQLiteConnection,command也要用SQLiteCommand,即一切与SQL相关到都要改为SQLite对应的,也包括要用SQLiteParameter。最后用try-catch捕获异常时一定要catch SQLiteExcepiton这个异常,不要捕获Exception否则你拿到的异常对象就会是null。

温故而知新《ADO.NET架构》
ADO.NET架构

  1. ExecuteNonQuery:执行非查询的sql语句,返回受影响的行数
  2. ExecuteScalar:执行非查询的sql语句,返回第一行第一列的值
  3. ExecuteReader:用来执行查询sql,按需读取(通过while循环),读取期间连接一直打开
  4. DataAdapter:用来执行查询sql,一次性读取数据并加载到内存里,通过fill方法填充到DataTable里,查询量太多时可能会OOM

2. 使用Dapper

与ADO.NET明显的一个不同是Dapper操作数据库时不需要自己手动open(事务操作除外)。

基类

    
    public class BaseDAL
    {
        public static T Execute<T>(string connectionString,Func<SQLiteConnection,T> func)
        {
            using(SQLiteConnection con=new SQLiteConnection(connectionString))
            {
                return func(con);
            }
        }
        public static T ExecuteTransaction<T>(string connectionString,Func<SQLiteConnection,SQLiteTransaction,T> func)
        {
            using(var con=new SQLiteConnection(connectionString))
            {
                con.Open();//执行事务时才需要手动open
                using(var trans=con.BeginTransaction())
                {
                    return func(con, trans);
                }
            }
        }
        public static void ExecuteTransaction(string connectionString, Action<SQLiteConnection,SQLiteTransaction> func)
        {
            using (var con = new SQLiteConnection(connectionString))
            {
                con.Open();//执行事务时才需要手动open
                using (var trans = con.BeginTransaction())
                {
                    func(con,trans);
                }
            }
        }
    }

子类:

    public class RegionDAL : BaseDAL
    {
        private static string conStr = ConnectString.StrFoundation;

        public static List<RegionVo> Search(RegionSo so)
        {
            string sql = "select * from JS_REGION where 1=1";
            if (so.regionCode != null)
                sql += " and regionCode=@regionCode";
            if (so.regionLevel != null)
                sql += " and regionLevel=@regionLevel";
            if (so.regionLevels != null)
                sql += " and regionLevel in @regionLevels";
            if (so.superiorRegionCode != null)
                sql += " and superiorRegionCode=@superiorRegionCode";
            var data = Execute(conStr, (con) =>
            {
                return con.Query<RegionVo>(sql, so).ToList();
            });
            return data;
        }

        /// <summary>
        /// 同步数据(事务)
        /// </summary>
        /// <param name="list"></param>
        /// <param name="maxVersion"></param>
        /// <returns></returns>
        public static void SyncData(List<RegionVo> list, long maxVersion)
        {
            ExecuteTransaction(conStr, (con, trans) =>
           {
               var putList = list.Where(o => o.operate != NJS.Entities.operateType.DELETE).ToList();
               var deleteList = list.Where(o => o.operate == NJS.Entities.operateType.DELETE).ToList();

               var count = con.Execute("replace into JS_REGION(namePath,regionCode,regionLevel,superiorRegionCode,superiorRegionId,id) values (@namePath,@regionCode,@regionLevel,@superiorRegionCode,@superiorRegionId,@id)", putList, trans);

               count = con.Execute("delete from JS_REGION where id = @id", deleteList, trans);

               count = con.Execute("update GE_SYNC_TABLE set CUR_VERSION=@version where TABLE_NAME ='JS_REGION'", new { version = maxVersion }, trans);
               trans.Commit();
           });

        }

        public static long GetSyncVersion()
        {
            var data = Execute<long>(conStr, con =>
            {
                var syncTables = con.Query<SysSyncTable>("select CUR_VERSION as curVersion from GE_SYNC_TABLE where TABLE_NAME ='JS_REGION'");
                return syncTables.FirstOrDefault()?.curVersion ?? 0;
            });
            return data;

        }
    }

参考:

1. 用了Dapper之后通篇还是SqlConnection,真的看不下去了
2. 温故而知新,由ADO.NET与Dapper所联想到的

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JimCarter

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值