ORM:数据库表的字段=>对应到类的属性
作用:利用对象 对关系型数据库进行操作,简化基础CURD的操作
常用的ORM:
- SqlSugar (国内)
- Dos.ORM (国内)
- Chloe (国内)
- StackExchange/Dapper (国外)
- Entity Framework (EF) (国外)
- NHibernate (国外)
- ServiceStack/ServiceStack.OrmLite (国外)
- linq2db (国外)
- Massive (国外)
- PetaPoco (国外)
EF Core
EF Core支持的数据库:MS SQL、Oracle、Mysql、PostgreSQL、SqlLite等
EF Core玩美支持MSSQL 对Mysql、PostgreSQL类开源数据库也还行 这三个比较常用。其他的数据库使用可能会有坑,不同数据库底层操作差异较大
EF Core环境搭建(需要Mysql或则SqlServer数据库):
1.创建实体类(code first)
2.创建DbContext;
3.生成数据库(数据库、表都是命令自动生成)
4.编写业务代码
新建控制台项目。
安装Package:
mysql:Install-Package Pomelo.EntityFrameworkCore.MySql
sqlserver:Install-Package Microsoft.EntityFrameworkCore.SqlServer
--Student (Model)
internal class Student { public long Id { get; set; } public string Name { get; set; } public int Age { get; set; } public string? Address { get; set; } }
--StudentConfig.cs
模型配置,主要用来设置表名/主键/字段对应关系/字段长度等、、
internal class StudentConfig : IEntityTypeConfiguration<Student> { public void Configure(EntityTypeBuilder<Student> builder) { builder.ToTable("ZuStudent");//设置表名,不写默认为类名 //系统自动把ID设置为主键了,所以不需要了 //builder.HasKey(t => t.Id); //设置主键 //builder.Property(x => x.Id).ValueGeneratedNever(); //设置自增 builder.Property(s => s.Name).HasMaxLength(60); //设置Name字段在数据库的长度 //一般不建议这样设置 builder.Property(s => s.Address).HasColumnName("Loaction");//设置Address属性 对应数据库的字段Location // } }
--StuDbContext.cs 数据库上下文(主要用来连接数据库和配置)
internal class StuDbContext:DbContext { public DbSet<Student> Students { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { base.OnConfiguring(optionsBuilder); string ConStr = "Server = 192.1.20.100\\SQLSERVER2016; Database = Demo; User Id = sa; Password = root;connection timeout=600"; optionsBuilder.UseSqlServer(ConStr);
//MySql
//string connStr = "Data Source=192.168.1.1;Database=Demo1;User ID=admin;Password=admin; Allow User Variables=True;";// sslMode=None;";
//var serVersion = new MySqlServerVersion(new Version(5, 7, 0));
//optionsBuilder.UseMySql(connStr, serVersion);
} protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);//从指定程序集加载配置 } }
生成数据库(Migration数据库迁移):
安装Package:
Install-Package Microsoft.EntityFrameworkCore.Tools
然后在 程序包管理器控制台 输入命令:
PM> Add-Migration Init
Add-Migration :数据库脚本生成指令 Init:是自定义的标记命名,可以自己根据生成的操作自己填写。例如:Add-Migration ChangeXXTableColumn
查看输出
系统会生成一个Migrations文件夹。
然后继续在 程序包管理器控制台 执行命令,update-database 让系统自动执行脚本;
来连接数据库看看:
如果需要修改模型结构,假设需要增加性别属性,如何将它更新到数据库:
internal class Student { public long Id { get; set; } public string Name { get; set; } public int Age { get; set; } public string? Address { get; set; } /// <summary> /// 0:女 1:男 /// </summary> public int Gender { get; set; } }
重复执行生成脚本和更新数据库的操作
1.PM> Add-Migration AddGenderToZuStudent
2.PM> update-database
再来观察数据库(刷新一下):
EF Core增删改查:
先给Student重写一下ToString();
--Program
using EFCore_01; using Microsoft.EntityFrameworkCore; Student st=new Student(); st.Name = "张三"; st.Age = 10; st.Gender = 0; st.Address = "北京市东城区"; string result= await AddStudent(st); Console.WriteLine(result); List<Student> sts = await SearchStudentForName("张三"); foreach (var item in sts) { Console.WriteLine(item.ToString()); } /* st.Name = "李四"; st.Age = 12; string result1 = await UpdateStudent(st); Console.WriteLine(result1); string result2 = await DeleteStudent(st); Console.WriteLine(result2); */ //查询-根据姓名 async Task<List<Student>> SearchStudentForName(string name) { using (StuDbContext sc = new StuDbContext()) { return sc.Students.Where(x => x.Name == name).ToList(); } }
//新增 async Task<string> AddStudent(Student stu) { try { using (DbContext sc = new StuDbContext()) { Student st = new Student(); st.Name = "张三"; st.Age = 10; st.Gender = 0; st.Address = "北京市东城区"; await sc.AddAsync(st);//增加一个学生记录(记录到内存中,并未写入数据库) await sc.SaveChangesAsync();//保存修改到数据库 } } catch (Exception e) { return "Error,新增学生失败:" + e.Message; } return $"OK:新增学生{st.Name}成功"; }
//修改 async Task<string> UpdateStudent(Student stu) { try { using (DbContext sc = new StuDbContext()) { Student st = new Student(); st.Name = "张三"; st.Age = 10; st.Gender = 0; st.Address = "北京市东城区"; sc.Update(st);//增加一个学生记录(记录到内存中,并未写入数据库) await sc.SaveChangesAsync();//保存修改到数据库 } } catch (Exception e) { return "Error,修改学生失败:" + e.Message; } return $"OK:修改学生{st.Name}成功"; }
//删除 async Task<string> DeleteStudent(Student stu) { try { using (DbContext sc = new StuDbContext()) { Student st = new Student(); st.Name = "张三"; st.Age = 10; st.Gender = 0; st.Address = "北京市东城区"; sc.Remove(st);//增加一个学生记录(记录到内存中,并未写入数据库) await sc.SaveChangesAsync();//保存修改到数据库 } } catch (Exception e) { return "Error,删除学生失败:" + e.Message; } return $"OK:删除学生{st.Name}成功"; }
运行:
先看控制台
再看数据库