zoukankan      html  css  js  c++  java
  • Sqlite-net 修改版 支持中文和CodeFirst技术

    最近, 做的一个windows 桌面WPF程序, 需要数据库支持。尝试了 sql server 的开发版,使用EF , 效率太低。后来采用sqlite数据库,中间踩坑无数。但最终完美的解决了这些问题。为了帮助广大程序员更好的使用sqlite ,今分享所有相关代码。

    sqlite , 是一款免费的数据库管理程序。可以嵌入到桌面应用程序、asp.net 网站应用程序中。对于不太复杂软件来说,是个不错的选择。

    sqlite-net , 是sqlite的扩展程序。支持codefirst,并自动迁移,笔者认为比EF好很多。也方便使用。但原版不支持中文(中文显示乱码),经本人修改后,已经支持中文了。

    CodeFirst 技术,是一种无需事先创建数据库,而是用C#代码创建业务对象(类)的方式,创建数据库。这种方式,减少了工作量,是理想的使用数据库的方式。

    要在WPF桌面软件中添加sqlite , 遵循以下步骤:

    1)  打开Visual Studio, 创建wpf 项目, 右键点击项目的”引用“文件夹,点:管理nuget程序包

    2)点“浏览”,搜索:sqlite, 选择第一项, 点安装。安装后生成项目。

    3)搜索:sqlite-net, 选择第一项,点安装。当前版本是:sqlite-net.1.6.292; 项目中会增加两个cs代码文件:SQLite.cs 和 SQLiteAsync.cs

    4)  重点:用如下代码替换 SQLite.cs文件的内容。这段代码是经过我的修改,支持中文。在此复制代码: https://www.cnblogs.com/lmp138/articles/11962112.html

    5)要应用sqlite-net, 首先,添加业务对象类。如下:统计表;注意:using SQLite;

    using SQLite;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Sqlite4
    {
        [Serializable]
        public class 统计表
        {
            [PrimaryKey, AutoIncrement]
            public long Id { get; set; }
    
            public string 表名称 { get; set; }
            public string 说明 { get; set; }
            public int 记录数 { get; set; }
            public int 序号 { get; set; }
            public DateTime 更新时间 { get; set; }
        }
    
    }
    View Code

    6) 创建SQLiteHelper类

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using System.Text;
    using System.Threading.Tasks;
    using SQLite;
    
    namespace Sqlite4
    {
        /// <summary>
        /// 处理数据库的操作。
        /// 需要 sqlite3.dll的配合,项目文件应添加该文件
        /// 本类,包含一个静态的字典,储存对数据库文件的连接。
        /// 构造函数可以指定不同的数据库文件
        /// </summary>
        public class SQLiteHelper : IDisposable
        {
            /// <summary>
            /// 互斥锁对象
            /// </summary>
            private static readonly object objForLock = new object();
            /// <summary>
            /// 连接字典: Key : 数据库的文件名,Value: 该文件的数据库连接
            /// </summary>
            private static readonly Dictionary<string, SQLiteConnection> ConnDic = new Dictionary<string, SQLiteConnection>();
    
            /// <summary>
            /// 连接
            /// </summary>
            private SQLiteConnection cnn = null;
    
            /// <summary>
            ///   打开数据库连接,日期时间采用字符串方式。
            /// </summary>
            /// <param name="dbPath">数据库的文件名</param>
            public SQLiteHelper(string dbPath)
            {
                if (ConnDic.ContainsKey(dbPath))
                {
                    cnn = ConnDic[dbPath];
                }
                else
                {
                    cnn = new SQLiteConnection(dbPath, false); // 数据库中,日期使用DateTime类型,而不是 Ticks
                    ConnDic.Add(dbPath, cnn);
                }
            }
            /// <summary>
            /// 关闭打开的文件连接
            /// </summary>
            public void Close()
            {
                ConnDic.Remove(cnn.DatabasePath);  // 从字典里删除
                cnn.Close();  // 关闭连接
            }
            /// <summary>
            /// 创建所有的表到数据库,表已存在不会重复创建
            /// 要增加表到数据库, 参考:ClassLibraryEF空间下的 CodeFirstClass.css文件
            /// </summary>
            public void CreateMyTables()
            {
                cnn.CreateTable<统计表>();
            
             }
     
    
            
    
            /// <summary>
            /// 删除一项
            /// </summary>
            /// <param name="obj"></param>
            /// <returns></returns>
            public int Delete(object obj)
            {
                lock (objForLock)
                {
                    return cnn.Delete(obj);
                }
            }
    
            /// <summary>
            /// 删除一组
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="list"></param>
            /// <returns></returns>
            public int DeleteRange<T>(IEnumerable<T> list)
            {
                lock (objForLock)
                {
                    int c = 0;
                    cnn.RunInTransaction(() =>
                    {
                        foreach (var item in list)
                        {
                            c += cnn.Delete(item);
                        }
                    });
    
                    return c;
                }
            }
    
            /// <summary>
            /// 删除表的所有内容
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <returns></returns>
            public int DeleteAll<T>()
            {
                lock (objForLock)
                {
                    return cnn.DeleteAll<T>();
                }
            }
    
            /// <summary>
            /// 插入数据
            /// </summary>
            /// <param name="data"></param>
            /// <returns></returns>
            public int Insert(object data)
            {
                lock (objForLock)
                {
                    return cnn.Insert(data);
                }
            }
            /// <summary>
            /// 插入数据
            /// </summary>
            /// <param name="objects"></param>
            /// <returns></returns>
            public int InsertAll(System.Collections.IEnumerable objects)
            {
                lock (objForLock)
                {
                    return cnn.InsertAll(objects);
                }
            }
    
            /// <summary>
            /// 更新一项
            /// </summary>
            /// <param name="obj"></param>
            /// <returns></returns>
            public int Update(object obj)
            {
                lock (objForLock)
                {
                    return cnn.Update(obj);
                }
            }
    
            public int UpdateAll(System.Collections.IEnumerable objects)
            {
                lock (objForLock)
                {
                    return cnn.UpdateAll(objects);
                }
            }
    
            /// <summary>
            /// 执行SQL命令
            /// </summary>
            /// <param name="sql"></param>
            /// <returns></returns>
            public int Execute(string sql)
            {
                lock (objForLock)
                {
                    return cnn.Execute(sql);
                }
            }
    
            /// <summary>
            /// 备份
            /// </summary>
            /// <param name="destFileName"></param>
            public void Backup(string destFileName)
            {
                lock (objForLock)
                {
                    File.Copy(cnn.DatabasePath, destFileName);
                }
            }
    
           
    
            /// <summary>
            /// 返回所有记录
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <returns></returns>
            public List<T> ToListAll<T>() where T : new()
            {
                lock (objForLock)
                {
                    Type tp = typeof(T);
                    string sql = $"select * from {tp.Name}";
                    return cnn.Query<T>(sql);
                }
            }
    
            /// <summary>
            /// 查询sql表示的记录
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="sql"></param>
            /// <returns></returns>
            public List<T> ToListSql<T>(string sql) where T : new()
            {
                lock (objForLock)
                {
                    return cnn.Query<T>(sql);
                }
            }
    
            /// <summary>
            /// 返回sql描述的记录
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="sql"></param>
            /// <returns></returns>
            public List<T> ToList<T>(string sql) where T : new()
            {
                lock (objForLock)
                {
                    return cnn.Query<T>(sql);
                }
            }
    
            /// <summary>
            /// 查询表的内容,使用SQL语句
            /// </summary>
            /// <param name="tableName"></param>
            /// <param name="sqlText"></param>
            /// <returns></returns>
            public IList<object> Query(string tableName, string sqlText)
            {
                lock (objForLock)
                {
                    Type tp = GetTypeByTableName(tableName);
                    if (tp == null)
                        return null;
                    SQLite.TableMapping tm = cnn.GetMapping(tp);
                    return cnn.Query(tm, sqlText);
                }
            }
    
            /// <summary>
            /// 获取表
            /// </summary>
            /// <param name="tableName"></param>
            /// <returns></returns>
            public IList<object> ToListByTableName(string tableName)
            {
                lock (objForLock)
                {
                    Type tp = GetTypeByTableName(tableName);
                    if (tp == null)
                        return null;
    
                    SQLite.TableMapping tm = cnn.GetMapping(tp);
                    return cnn.Query(tm, $"select * from {tableName}");
                }
            }
    
            /// <summary>
            /// 根据表名称,获得类型
            /// </summary>
            /// <param name="tableName"></param>
            /// <returns></returns>
            public Type GetTypeByTableName(string tableName)
            {
                Assembly assembly = Assembly.Load("ClassLibraryEF");
                Type[] types = assembly.GetTypes();
    
                foreach (Type tp in types)
                {
                    if (tp.Name == tableName)
                        return tp;
                }
                return null;
            }
     
    
            /// <summary>
            /// 获取表的行数
            /// </summary>
            /// <param name="tableName"></param>
            /// <returns></returns>
            public int GetCountOfTable(string tableName)
            {
                lock (objForLock)
                {
                    return cnn.CreateCommand($"select count(*) from {tableName}").ExecuteScalar<int>();
                }
            }
    
            /// <summary>
            /// Sqlite标准时间
            /// </summary>
            /// <param name="dt"></param>
            /// <returns></returns>
            public string SqliteDateTimeStr(DateTime dt)
            {
                return dt.ToString("yyyy-MM-ddTHH:mm:ss");
            }
    
            /// <summary>
            /// Sqlite标准时间字符串,日期的最后一秒
            /// </summary>
            /// <param name="dt"></param>
            /// <returns></returns>
            public string SqliteDateTimeStr_EndDayTime(DateTime dt)
            {
                return dt.ToString("yyyy-MM-ddT23:59:59");
            }
    
            /// <summary>
            /// Sqlite标准时间字符串,日期的开始0秒
            /// </summary>
            /// <param name="dt"></param>
            /// <returns></returns>
            public string SqliteDateTimeStr_BeginDayTime(DateTime dt)
            {
                return dt.ToString("yyyy-MM-ddT00:00:00");
            }
    
            /// <summary>
            /// 释放时,无需释放任何对象,因为采用静态的Sqlite连接。
            /// 如果释放静态连接,之后的实例将重新创建连接,太频繁
            /// </summary>
            public void Dispose()
            {
    
            }
        }
    }
    View Code

    7)创建SqliteDb类

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Sqlite4
    {
        /// <summary>
        /// sqlite 数据库管理,
        /// </summary>
        class SqliteDb : SQLiteHelper
        {
            private static string path = "d:\data1.db";  // 任意本地数据文件名,如果不存在该文件会自动创建
    
            public SqliteDb() : base(path)
            {
    
    
            }
    
            /// <summary>
            /// 获取表的所有记录
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <returns></returns>
            public static List<T> GetList<T>() where T : new()
            {
                using (SqliteDb db = new SqliteDb())
                {
                    return db.ToListAll<T>();
                }
            }
            /// <summary>
            /// 表中获取某个代码的第一项记录
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="code"></param>
            /// <returns></returns>
            public static T GetItem<T>(string code) where T : new()
            {
                using (SqliteDb db = new SqliteDb())
                {
                    string tableName = typeof(T).Name;
                    var sql = $"select * from {tableName} where 代码 = '{code}'";
                    var list = db.ToList<T>(sql);
                    if (list.Count > 0)
                        return list[0];
                    return default(T);
                }
            }
            /// <summary>
            /// 返回指定代码的所有记录
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="code"></param>
            /// <returns></returns>
            public static List<T> GetItems<T>(string code) where T : new()
            {
                using (SqliteDb db = new SqliteDb())
                {
                    string tableName = typeof(T).Name;
                    var sql = $"select * from {tableName} where 代码 = '{code}'";
                    return db.ToList<T>(sql);
                }
            }
        }
    }
    View Code

    8)添加:sqlite3.dll到项目文件中。生成项目,则项目的Release文件夹下,多了两个文件夹:x64 和x86; 分别存储64位和32位的sqlite驱动程序;根据你程序的位数,添加需要的sqlite3.dll到项目中,生成操作:内容;复制到输出目录:如果较新则复制。

    9)MainWindow.xaml文件中,添加表:

      <DataGrid x:Name="dg1" />

    10)主窗口中添加事件: Loaded="Window_Loaded"

    11)添加事件处理程序:

            private void Window_Loaded(object sender, RoutedEventArgs e)
            {
                try
                {
                LoadDb();
    
                }
                catch(Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            /// <summary>
            /// 载入数据库内容
            /// </summary>
            private void LoadDb()
            {
                using(SqliteDb db = new SqliteDb())
                {
                    db.CreateMyTables();
    
                    统计表 t = new 统计表()
                    { 序号 = 1, 更新时间 = DateTime.Now, 表名称 = "A表", 记录数 = 100, 说明 = "测试" };
    
                    db.Insert(t);
    
                    this.dg1.ItemsSource = db.ToListAll<统计表>();
                }
            }
    View Code

    12)生成项目

    13)运行

     

    14) 如果要修改统计表的内容,只需修改该类即可。sqlite-net 会自动迁移,给数据库增加相关的列。

    15)增删改查请参考:上面的SQLiteHelper类中的函数即可。

    本文章涉及的源代码下载 : https://files.cnblogs.com/files/lmp138/Sqlite4.7z

    希望能帮助到您!

  • 相关阅读:
    第一章 Java Collections Framework总览
    MySQL常用sql语句
    static关键字
    Mysql常用索引及优化
    JDK安装及环境变量配置
    破解IntelliJ IDEA 2017
    Spring自我总结
    Java中根据字节截取字符串
    外键的主要作用:保持数据的一致性、完整性
    使用SSI框架写的简单Demo(查询模块)
  • 原文地址:https://www.cnblogs.com/lmp138/p/11962095.html
Copyright © 2011-2022 走看看