随笔 - 59  文章 - 20  评论 - 61  阅读 - 85494

VS2015 Winform使用SQLite的三种ORM方案

SQLite.Net-PCL

新建Winform项目,NuGet查找SQLite.Net-PCL,选择sqlite-net-pcl,注意,查找结果有好几个非常接近的,我们选择的程序包项目URL是https://github.com/praeclarum/sqlite-net,不要搞错了。
这里写图片描述
定义实体类:

public class Book
    {
        [PrimaryKey, AutoIncrement]
        public int id { get; set; }

        public string Name { get; set; }//书名

        public DateTime PublishDate { get; set; }//出版日期

        public string Author { get; set; }//作者

        public float Price { get; set; }//价格
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

定义数据库,在数据库的构造函数中创建数据表:

public class MyBookDB : SQLiteConnection
    {
        //定义属性,便于外部访问数据表
        public TableQuery<Book> Books { get { return this.Table<Book>(); } }

        public MyBookDB(string dbPath) : base(dbPath)
        {
            //创建数据表
            CreateTable<Book>();
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

Winform窗口设计非常简单,演示对数据库的增删改查,操作完成后,点击更新按钮,显示数据表全部记录,确认操作结果。表格控件用DataGridView。
这里写图片描述
Form1_Load初始化数据库文件路径:

//数据库文件路径
        private string dbPath;
        private void Form1_Load(object sender, EventArgs e)
        {
            //数据库文件路径就在运行目录下
            dbPath = $"{Environment.CurrentDirectory}\\mybooks.db";
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

增加

private void btnAdd_Click(object sender, EventArgs e)
        {
            List<Book> books = new List<Book>()
            {
                new Book() { Name = "射雕英雄传", PublishDate = new DateTime(1960, 1, 1), Author = "金庸", Price = 10.5f },
                new Book() { Name = "神雕侠侣", PublishDate = new DateTime(1960, 2, 2), Author = "金庸", Price = 12.5f },
                new Book() { Name = "倚天屠龙记", PublishDate = new DateTime(1960, 3, 3), Author = "金庸", Price = 16.5f },
                new Book() { Name = "小李飞刀", PublishDate = new DateTime(1965, 5, 5), Author = "古龙", Price = 13.5f },
                new Book() { Name = "绝代双骄", PublishDate = new DateTime(1965, 6, 6), Author = "古龙", Price = 15.5f },
            };

            using (var db = new MyBookDB(dbPath))
            {
                int count = db.InsertAll(books);
                this.Text = $"{DateTime.Now}, 插入{count}条记录";
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

修改

private void btnModify_Click(object sender, EventArgs e)
        {
            using (var db = new MyBookDB(dbPath))
            {
                var book = db.Books.FirstOrDefault(x => x.Name == "绝代双骄");
                if (book != null)
                {
                    book.Price += 1;
                    int count = db.Update(book);
                    this.Text = $"{DateTime.Now}, 修改{count}条记录";
                }
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

删除

private void btnDel_Click(object sender, EventArgs e)
        {
            using (var db = new MyBookDB(dbPath))
            {
                int count = db.Books.Delete(x => x.Name == "绝代双骄");
                this.Text = $"{DateTime.Now}, 删除{count}条记录";
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

查询

private void btnQuery_Click(object sender, EventArgs e)
        {
            using (var db = new MyBookDB(dbPath))
            {
                var books = db.Books.Where(x => x.Author == "金庸").OrderByDescending(x => x.PublishDate).ToList();
                this.Text = $"{DateTime.Now}, 查到{books.Count}条记录";
                this.dataGridView1.DataSource = books;
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

刷新

private void btnRefresh_Click(object sender, EventArgs e)
        {
            using (var db = new MyBookDB(dbPath))
            {
                var books = db.Books.ToList();
                this.dataGridView1.DataSource = books;
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

访问数据库的代码非常简单,类似EF,但是有一点点差异,数据表的类型是TableQuery,不是DBSet,所以增加、修改记录的函数有点差异。

System.Data.SQLite+SQLite.CodeFirst

新建Winform项目,NuGet安装System.Data.SQLite,它会自动安装EF6.0。
这里写图片描述
然后安装SQLite.CodeFirst,它会自动升级EF到6.1.0。一定要再把EF升级到6.1.3,否则运行会报错The type of the key field ‘id’ is expected to be ‘System.Int32’, but the value provided is actually of type ‘System.Int64’.

这里写图片描述

然后在App.Config中添加一行

<providers>
      <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
      <!--手工添加下面一行-->
      <provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6" />
    </providers>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

然后添加数据库连接字符串

<connectionStrings>
    <add name="dbConn" connectionString="data source=mytest1.db" providerName="System.Data.SQLite.EF6" />
  </connectionStrings>
  • 1
  • 2
  • 3
  • 4

定义实体类,跟EF一样:

public class Book
    {
        public int id { get; set; }

        public string Name { get; set; }//书名

        public DateTime PublishDate { get; set; }//出版日期

        public string Author { get; set; }//作者

        public float Price { get; set; }//价格
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

定义数据库,在数据库的构造函数中创建数据表:

public class MyBookDB : DbContext
    {
        //定义属性,便于外部访问数据表
        public DbSet<Book> Books { get { return Set<Book>(); } }

        public MyBookDB() : base("dbConn")
        {

        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            //base.OnModelCreating(modelBuilder);
            ModelConfiguration.Configure(modelBuilder);
            var init = new SqliteCreateDatabaseIfNotExists<MyBookDB>(modelBuilder);
            Database.SetInitializer(init);
        }

    }

    public class ModelConfiguration
    {
        public static void Configure(DbModelBuilder modelBuilder)
        {
            ConfigureBookEntity(modelBuilder);
        }
        private static void ConfigureBookEntity(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Book>();
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

增删改查的代码跟EF一样:

private void btnAdd_Click(object sender, EventArgs e)
        {
            List<Book> books = new List<Book>()
            {
                new Book() { Name = "射雕英雄传", PublishDate = new DateTime(1960, 1, 1), Author = "金庸", Price = 10.5f },
                new Book() { Name = "神雕侠侣", PublishDate = new DateTime(1960, 2, 2), Author = "金庸", Price = 12.5f },
                new Book() { Name = "倚天屠龙记", PublishDate = new DateTime(1960, 3, 3), Author = "金庸", Price = 16.5f },
                new Book() { Name = "小李飞刀", PublishDate = new DateTime(1965, 5, 5), Author = "古龙", Price = 13.5f },
                new Book() { Name = "绝代双骄", PublishDate = new DateTime(1965, 6, 6), Author = "古龙", Price = 15.5f },
            };

            using (var db = new MyBookDB())
            {
                db.Books.AddRange(books);
                int count = db.SaveChanges();
                this.Text = $"{DateTime.Now}, 插入{count}条记录";
            }
        }

        private void btnModify_Click(object sender, EventArgs e)
        {
            using (var db = new MyBookDB())
            {
                var book = db.Books.FirstOrDefault(x => x.Name == "绝代双骄");
                if (book != null)
                {
                    book.Price += 1;
                    int count = db.SaveChanges();
                    this.Text = $"{DateTime.Now}, 修改{count}条记录";
                }
            }
        }

        private void btnDel_Click(object sender, EventArgs e)
        {
            using (var db = new MyBookDB())
            {
                var book = db.Books.FirstOrDefault(x => x.Name == "绝代双骄");
                if (book != null)
                {
                    var result = db.Books.Remove(book);
                    int count = db.SaveChanges();
                    this.Text = $"{DateTime.Now}, 删除{count}条记录";
                }
            }
        }

        private void btnQuery_Click(object sender, EventArgs e)
        {
            using (var db = new MyBookDB())
            {
                var books = db.Books.Where(x => x.Author == "金庸").OrderByDescending(x => x.PublishDate).ToList();
                this.Text = $"{DateTime.Now}, 查到{books.Count}条记录";
                this.dataGridView1.DataSource = books;
            }
        }

        private void btnRefresh_Click(object sender, EventArgs e)
        {
            using (var db = new MyBookDB())
            {
                var books = db.Books.ToList();
                this.dataGridView1.DataSource = books;
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66

EF Core

重新打开VS2015,新建Winform项目,采用新的解决方案,NuGet安装Microsoft.EntityFrameworkCore.Sqlite。
这里写图片描述

然后安装Microsoft.EntityFrameworkCore.Tools。
这里写图片描述

定义实体类,跟EF一样:(同上)

定义数据库:

public class MyBookDB : DbContext
    {
        public DbSet<Book> Books { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            //base.OnConfiguring(optionsBuilder);
            optionsBuilder.UseSqlite("Filename=my1.db");
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

增删改查的代码跟EF一样:(同上)
然后编译项目。
运行程序包管理器控制台
这里写图片描述

执行Add-Migration my1,系统自动创建了一个文件夹和2个文件
这里写图片描述

打开看看,有创建数据库的代码

public partial class my1 : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "Books",
                columns: table => new
                {
                    id = table.Column<int>(nullable: false)
                        .Annotation("Sqlite:Autoincrement", true),
                    Author = table.Column<string>(nullable: true),
                    Name = table.Column<string>(nullable: true),
                    Price = table.Column<float>(nullable: false),
                    PublishDate = table.Column<DateTime>(nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Books", x => x.id);
                });
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropTable(
                name: "Books");
        }
    }

[DbContext(typeof(MyBookDB))]
    partial class MyBookDBModelSnapshot : ModelSnapshot
    {
        protected override void BuildModel(ModelBuilder modelBuilder)
        {
            modelBuilder
                .HasAnnotation("ProductVersion", "1.1.2");

            modelBuilder.Entity("EFCoreSqlite.Book", b =>
                {
                    b.Property<int>("id")
                        .ValueGeneratedOnAdd();

                    b.Property<string>("Author");

                    b.Property<string>("Name");

                    b.Property<float>("Price");

                    b.Property<DateTime>("PublishDate");

                    b.HasKey("id");

                    b.ToTable("Books");
                });
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

然后运行Update-Database,在程序运行目录下创建了my1.db。
然后就可以运行项目测试增删改查了。
注意:
1,不要直接在之前2个项目的解决方案中添加EF Core项目,否则Add-Migration会报错The EntityFramework package is not installed on project
2,Add-Migration之前先重新生成项目,否则报错Build failed。
这里写图片描述

小结

在Winform软件中,如果对数据库性能要求不高的话,可以使用SQLite,最大好处是减少安装包体积。如果采用SQL Server Express的话,安装包几百M,就算采用精简的LocalDB,安装包也有几十M,但是用SQLite打包,则只有几M。
对于SQLite.Net-PCL项目,用InstallShield打包时,注意勾选内容文件,否则会缺少e_sqlite3.dll文件。
这里写图片描述

SQLite.Net-PCL的好处是引入的库比较少,如果移动客户端采用Xamarin开发,可以实现PC客户端和移动客户端共享数据库模块的代码。坏处就是数据库访问代码跟EF标准不大一样。
System.Data.SQLite+SQLite.CodeFirst的好处就是访问数据库的代码完全等同EF,理论上可以更换数据库类型而不用修改上层代码。
EF Core则比较麻烦,不能自动化创建数据库,每次更改数据库还要手工输入命令升级数据库,而且引入的库非常多,感觉非常不爽。

原文链接: https://blog.csdn.net/woodsun2008/article/details/72861763
posted on   SunnyTrudeau  阅读(4054)  评论(2编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示