PC端工业应用开发宝典3-数据持久化

3 数据持久化

0 场景

软件跟一个设备可以通讯了,设备返回一些数据,我希望把这些数据存储起来,下次打开软件的时候能够浏览这次的数据

1 为什么使用数据库

磁盘存储数据是通过磁阻变化存储数据的

硬件设备上的信息存储是寄存器存储的

而我们想存储的数据是通过数据库存储的,因为查询效率高,如果是文件形式存储的话,想读一个数据只有把它之前的所有数据都读取才行,这样效率很慢

但有时候我们也会把一些设置放在文件里:

比如说读取版本号,这跟业务逻辑无关,只需要升级程序读取,那么就不需要引用一堆数据库操作的库。

比如设置语言,一台电脑两个用户用,一个用中文,一个用英文,一个语言字段需要对应两个用户,那么最好的办法就是把语言配置文件放在每个用户下的AppData文件目录。

比如我们开放一些字段可以用户自己修改,而不需要操作数据库。

2 连接数据库

我们使用ORM框架去连接数据库。

什么是ORM?

软件跟数据库通讯的思路是:

1 我们去数据库查询是通过数据库认识的SQL语句查询的,我们要写SQL语句去查询数据

1 我们去数据库查询是通过数据库认识的SQL语句查询的,我们要写SQL语句去查询数据

2 数据查出来之后我们需要构建一个个对应的类,创建这些类的对象去承载这些数据结构,

3 软件调用这些对象去进行计算,显示。

ORM框架(这里只Entity Framework)帮我们完成了上面的三步。

通过ORM框架你只需要:

创建数据的承载类,之后调用ORM框架的查询方法就能获取查询对象。

推荐用微软官方的ORM 框架Entity Framework去连接数据库,功能够强大,追求轻量化会写SQL的可以用Dapper,或者一些其他的国产SQL SUGAR /FREE SQL

Entity Framework Code First模式

Code First模式省去了你去建库建表的时间,你只需要把数据类型设计出来,EF会根据你设计的数据类去自动构建,后期如果你修改了模型,ef也会根据魔性的修改响应修改数据库,简而言之,数据库这方面不用你操心了,写好自己的代码就ok。

3 EF Code First实战

1 Nuget安装框架库

  • System.Data.SQLite

  • SQLite.CodeFirst

2 改动一下app.config

  • 在providers下再添加System.Data.SQLite节点
 <entityFramework>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer"/>
      <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6"/>
      <!--新增-->
      <provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6"/>
    </providers>
  </entityFramework>
  • configuration下添加新的连接字符串节点connectionStrings
<connectionStrings>
    <add name="MySqlite" connectionString="data source=.\Local.db" providerName="System.Data.SQLite.EF6"/>
  </connectionStrings>
  • 以下为完整app.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
  <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
  <section name="entityFramework"
    type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
    requirePermission="false"/>
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/>
  </startup>
  <entityFramework>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer"/>
      <provider invariantName="System.Data.SQLite.EF6" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6"/>
      <!--新增-->
      <provider invariantName="System.Data.SQLite" type="System.Data.SQLite.EF6.SQLiteProviderServices, System.Data.SQLite.EF6"/>
    </providers>
  </entityFramework>
  <system.data>
    <DbProviderFactories>
      <remove invariant="System.Data.SQLite.EF6"/>
      <add name="SQLite Data Provider (Entity Framework 6)" invariant="System.Data.SQLite.EF6"
        description=".NET Framework Data Provider for SQLite (Entity Framework 6)" type="System.Data.SQLite.EF6.SQLiteProviderFactory, System.Data.SQLite.EF6"/>
      <remove invariant="System.Data.SQLite"/>
      <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".NET Framework Data Provider for SQLite"
        type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite"/>
    </DbProviderFactories>
  </system.data>
  <!--新增-->
  <connectionStrings>
    <add name="MySqlite" connectionString="data source=.\Local.db" providerName="System.Data.SQLite.EF6"/>
  </connectionStrings>
</configuration>

2 建立数据模型

这个模型类方便软件内调用,也为了承载数据库查询出来的数据

public class Category
    {
        public string CategoryId { get; set; }
        public string Name { get; set; }
        public virtual ICollection<Product> Products { get; set; }
    }
 public class Product
    {
        public int ProductId { get; set; }
        public string Name { get; set; }
        public string CategoryId { get; set; }
        public virtual Category Category { get; set; }
    }

3 建立DBContext

DBContext是实体类与数据库之间的桥梁,通过这个类去查询数据,并返回对象。

 public class ProductContext : DbContext
    {
        public ProductContext():base("name=MySqlite")
        { }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            var initializer = new SqliteDropCreateDatabaseWhenModelChanges<MyDbContext>(modelBuilder);
            Database.SetInitializer(initializer);
        }

        public DbSet<Category> Categories { get; set; }
        public DbSet<Product> Products { get; set; }
    }

name=MySqlite 对应上文app.config里面的connectionStrings.Name

启动Main()

 class Program
    {
        static void Main(string[] args)
        {
            using (var db = new ProductContext())
            {
                // 增 
                var food = new Category { CategoryId = "FOOD", Name = "Foods" };
                db.Categories.Add(food);
                int recordsAffected = db.SaveChanges();
                Console.WriteLine("Saved {0} entities to the database, press any key to exit.", recordsAffected);
                Console.ReadKey();
            }
        }
    }

此时做了两步操作:

1 创建Local数据库并按照ProductContext里面的两个DbSet,分别按照模型建立Categories和Products两张表

2 在Category表里添加一个新的Category行

参考app.config里面设置的数据库位置connectionString="data source=.\Local.db"

我们可以看到数据库已经自己生成,并按照我们想要的添加了一行新的数据

至此,数据存储方面算是跑通了,我们只需要关注于代码中的数据模型就ok了。

参考

https://docs.microsoft.com/en-us/ef/ef6/fundamentals/configuring/connection-strings

https://www.cnblogs.com/hippieZhou/archive/2018/08/04/9420432.html

posted @ 2021-01-05 15:20  猝不及防  阅读(160)  评论(0编辑  收藏  举报