C#快速搭建模型資料庫SQLite操作

TA遠方發表於2019-07-22

using SQLite;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DAL
{
    // 用於實現操作模型資料類的介面
    public interface DalAdapter<T>
    {
        T QueryInfo(SQLiteConnection db, string selectSql, params Object[] values);

        List<T> QueryList(SQLiteConnection db, string selectSql, params Object[] values);
        List<T> QueryList(SQLiteConnection db, string selectSql);
    }
}
複製程式碼

using Model;
using SQLite;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

namespace DAL
{
    // 用於可被繼承運算元據模型類的基本類
    public class Dal<T>
    {
        protected string _tablename = "tablename", _dbname = "";
        private DalAdapter<T> __da;

        public static Semaphore lockTask = new Semaphore(1, 1);
        
        /// <summary>
        /// 表在的資料庫檔名
        /// </summary>
        /// <param name="dbName"></param>
        public Dal(string dbName=null)
        {
            if (string.IsNullOrEmpty(dbName)) dbName = DbFactory.default_db_path;
            _tablename = typeof(T).Name;
            _dbname = dbName;
        }

        /// <summary>
        /// 繼承基類的,派生類構造方法必須執行初始化 Init(this);
        /// </summary>
        /// <param name="da"></param>
        public void Init(DalAdapter<T> da)
        {
            __da = da;
        }
        
        /// <summary>
        /// 建立表
        /// </summary>
        /// <param name="isClear">預設清空已存在的表記錄</param>
        /// <returns></returns>
        public bool CreateTable(bool isClear = true)
        {
            using (var db = GetDb())
            {
                int c = db.CreateTable<T>();
                if (isClear && c == 0)
                {
                    db.DeleteAll<T>();
                    return true;
                }
                return true;
            }
        }

        /// <summary>
        /// 從一個模型類中獲取欄位
        /// </summary>
        /// <param name="model"></param>
        //public Dictionary<string, string> GetTableFiledAllFormModel(T model)
        //{
                //待補充...
                // PRAGMA table_info('tablename')
        //}

        /// <summary>
        /// 升級表處理
        /// </summary>
        /// <param name="fields">判斷和增加的欄位 key欄位名,value資料型別</param>
        public void UpgradeTable(Dictionary<string,string> fields)
        {
            // 判斷和增加的欄位,就是列出列名,然後判斷是否增加.或者修改.
            string selectSql = $"pragma table_info ({_tablename})";//列名錶是空的
            using (var db = GetDb())
            {
                var list = db.Query<table_info>(selectSql);
                if (list.Count > 0)
                {
                    foreach (var field in fields)
                    {
                        if (!list.Exists(p => p.name == field.Key))
                        //if (db.Execute($"select COUNT(*) from information_schema.columns WHERE table_name = '{_tablename}' and column_name = '{field.Key}'")>1)
                        {
                            //新增表欄位
                            //$"ALTER TABLE {_tablename} ADD COLUMN {fieldName} {fieldtype}"
                            db.Execute($"ALTER TABLE {_tablename} ADD COLUMN {field.Key} {field.Value}");
                        }
                    }
                }
            }
        }
        // 插入一條資料模型
        public bool InsertInfo(T info)
        {
            using(var db = GetDb())
            {
                return db.Insert(info) > 0;
            }
        }
        // 刪除一條資料模型, id 是有 primary_key
        public bool DeleteInfo(int id)
        {
            using(var db = GetDb())
            {
                return db.Delete<T>(id) > 0;
            }
        }
        // 更新一條記錄, 記得 id 主鍵
        public bool UpdateInfo(T info)
        {
            using(var db = GetDb())
            {
                return db.Update(info) > 0;
            }
        }
        // 查詢一條記錄, 需要一個 id
        public T QueryInfo(int id)
        {
            using (var db = GetDb())
            {
                return __da.QueryInfo(db, $"select * from {_tablename} where id=?", id);
            }
        }
        // 查詢一條記錄,有條件的, whereSql 是查詢where後的語句, values是傳?對應的條件條件值
        public T QueryInfoFromWhere(string whereSql, params Object[] values)
        {
            using(var db = GetDb())
            {
                return __da.QueryInfo(db, $"select * from {_tablename} where "+whereSql+" limit 1", values);
            }
        }
        // 查詢多條記錄,有條件的,查詢方式同上
        public List<T> QueryListFromWhere(string whereSql, params Object[] values)
        {
            using(var db = GetDb())
            {
                return __da.QueryList(db, $"select * from {_tablename} where " + whereSql, values);
            }
        }
        // 預設查所有記錄
        public List<T> QueryListAll()
        {
            using(var db = GetDb())
            {
                return __da.QueryList(db, $"select * from {_tablename}");
            }
        }
        // 刪除多條記錄, 只刪ids對應的
        public bool DeleteInfoes(List<int> ids)
        {
            string idsStr = string.Join(",", (from f in ids select f));
            using (var db = GetDb())
            {
                return db.Execute($"delete from {_tablename} where id in (?)", idsStr) > 0;
            }
        }
        // 刪除所有記錄
        public bool DeleteListAll()
        {
            using(var db = GetDb())
            {
                return db.DeleteAll<T>()>0;
            }
        }

        // 更新多條記錄,注意id主鍵
        public bool UpdateInfoes(List<T> infoes)
        {
            using (var db = GetDb())
            {
                return db.UpdateAll(infoes)>0;
            }
        }
        // 連線資料庫用的,不用管
        public SQLiteConnection GetDb()
        {
            string dbPath = DbFactory.getAppDataPath(_dbname);
            lockTask.WaitOne();
            return new SQLiteConnection(dbPath, new Action(() => { lockTask.Release(); }));
        }
    }
}
複製程式碼


綜上所述,基本實現例子如下:

資料庫是SQLite,

一, 寫好一個資料模型類, 類名隨意

publilc class ModelName{
    [PrimaryKey, Autoincrement]
    public int id = 0;
    public string name { set; get; }
    public int age { set; get; }}複製程式碼

二,在寫一個資料模型操作的類,類名與資料模型類名一似,以便區分

// 繼承了基本類,介面
public class ModeNameDal : Dal<ModeName>, DalAdapter<ModeName>
{
    // 構造方法中初始化
    public ModeName()
    {
        // 呼叫父類中的初始化方法
        init(this);
    }

    // 接下來就是由VS自動生成實現介面的方法了
    // 還可以呼叫父類已定義好的操作模型資料方法
    // 相信,如果你看懂怎麼用, 那這樣就不錯了...
}複製程式碼

三, 接下來就可以建立和運算元據庫模型

var dal = new ModeNameDal();
var info = dal.QueryInfo(0); // 查詢一條記錄
if (info != null) // info 模型
// ...
var list = dal.QueryListAll(); // 查詢所有複製程式碼


相關文章