Entity Framework Core简单使用
它是微软官方发布的基于ADO.NET的ORM框架。通过EF可以很方便地将表映射到实体对象或将实体对象转换为数据库表。
ORM:将数据存储从域对象自动映射到关系型数据库的工具。ORM主要包括3个部分:域对象、关系数据库对象、映射关系。ORM使类提供自动化CRUD,使开发人员从数据库API和SQL中解放出来。
EFCore有2种开发模式:
1. 从数据库生成Class实体类(DataFirst);
2. 由实体类生成数据库表结构(CodeFirst);
EFCore主要特点:
1. 支持多种数据库:SQLServer、MySQL、SQLite等。
2. 支持LINQ查询
3. 支持迁移,当EFCore模型更改时通过几条命令即可转换为数据库表
4. 支持原生sql语句,面对复杂查询性能欠佳时可以使用原生sql进行查询
一、通过EF Core创建数据库表
一般采用代码优先(CodeFirst)的方式,需要先编写实体类,再生成数据库表。
1. 创建实体类
1.1 FluentAPI方式创建(推荐)
先创建实体类再对实体类进行配置
internal class Book { public long Id { get; set; } /// <summary> /// 标题 /// </summary> public string Title { get; set; } /// <summary> /// 发布日期 /// </summary> public DateTime PubTime { get; set; } /// <summary> /// 单价 /// </summary> public Double Price { get; set; } /// <summary> /// 作者名字 /// </summary> public string AuthorName { get; set; } }
创建一个实现了IEntityTypeConfiguration接口的实体类的配置类BookEntityConfig,它用于配置实体类和数据库表的对应关系
// 使用此接口指定要对哪个实体类进行配置 internal class BookEntityConfig : IEntityTypeConfiguration<Book> { //对实体类和数据库表的关系进行详细配置 public void Configure(EntityTypeBuilder<Book> builder) { //设置表名 builder.ToTable("T_Books"); //设置Title字段最大值为50,并不能为空 builder.Property(e => e.Title).HasMaxLength(50).IsRequired(); builder.Property(e => e.AuthorName).HasMaxLength(20).IsRequired(); } }
1.2 通过数据注解的方式配置实体类
如果使用数据注解方式配置实体类,直接在定义类中的属性时,配置相应的注解即可。
public class Student { [Key] public long Id { get; set; } [MaxLength(50)] [Unicode] [Required] public string Name { get; set; } [MaxLength(50)] [Unicode] [Required] public string Class { get; set; } public int Age { get; set; } [MaxLength(50)] [Unicode] [Required] public string Sex { get; set; } }
2. 创建DbContext
创建实体类之后,需要创建继承自DbContext类的上下文类,并添加DbSet<实体>属性,该属性用于后续对表的操作。
internal class TestDbContext:DbContext { //定义实体类属性,后续增删改查都用此对象 public DbSet<Book> Books { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { //配置连接数据库字符串 string connStr = "Data Source=REDMIBOOKPRO15\\SQL;Initial Catalog=EFCore;Integrated Security=True;Trust Server Certificate=True"; //指定使用SqlServer数据库进行连接 optionsBuilder.UseSqlServer(connStr); } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); //加载当前程序集中所有实现了IEntityTypeConfiguration接口的类 modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly); } }
3. 通过实体类生成数据库表
安装Microsoft.EntityFrameworkCore.Tools包
1. 在【程序包管理器控制台】中执行如下命令:Add-Migration InitialCreate InitialCreate:给这次迁移取的名字

2. 执行成功后会生成Migrations文件夹,以及迁移配置文件
3. 执行 Update-database 命令执行数据库迁移代码
4. 查看数据库,此时表已经创建完成

二、EF Core的增删改查
1. 插入数据
using efCore; //创建上下文对象,并使用using自动释放资源 using TestDbContext ctx = new TestDbContext(); //创建book对象数据 var b1 = new Book { AuthorName = "杨中科", Title = "零基础趣学C语言", Price = 59.8, PubTime = new DateTime(2019, 3, 1) }; var b2 = new Book { AuthorName = "Robert Sedgewick", Title = "算法(第4版)", Price = 99, PubTime = new DateTime(2012, 10, 1) }; var b3 = new Book { AuthorName = "吴军", Title = "数学之美", Price = 69, PubTime = new DateTime(2020, 5, 1) }; var b4 = new Book { AuthorName = "杨中科", Title = "程序员的SQL金典", Price = 52, PubTime = new DateTime(2008, 9, 1) }; var b5 = new Book { AuthorName = "吴军", Title = "文明之光", Price = 246, PubTime = new DateTime(2017, 3, 1) }; //添加数据 ctx.Books.Add(b1); ctx.Books.Add(b2); ctx.Books.Add(b3); ctx.Books.Add(b4); ctx.Books.Add(b5); //将数据提交保存到数据库 await ctx.SaveChangesAsync();
2. 查询
using efCore; //创建上下文对象,并使用using自动释放资源 using TestDbContext ctx = new TestDbContext(); //查询所有书 foreach(Book book in ctx.Books) { Console.WriteLine($"Id={book.Id},Title={book.Title},Price={book.Price}"); } //查询价格高于80的书 IEnumerable<Book> books2 = ctx.Books.Where(b => b.Price > 80); foreach (Book book in books2) { Console.WriteLine($"Id={book.Id},Title={book.Title},Price={book.Price}"); } //查询单条数据,如果找不到则会报错 Book b1 = ctx.Books.Single(b=>b.Title=="零基础趣学C语言"); Console.WriteLine(b1.Title); //查询单条数据,找不到返回null Book? b2 = ctx.Books.FirstOrDefault(b=>b.Id==9); if(b2 == null) { Console.WriteLine("没有ID为9的数据"); } else { Console.WriteLine(b2.Title); } //按照价格排序 IEnumerable<Book> books = ctx.Books.OrderByDescending(b => b.Price); foreach(Book book in books) { Console.WriteLine($"Id={book.Id},Title={book.Title},Price={book.Price}"); }
3. 修改
using efCore; using TestDbContext ctx = new TestDbContext(); Book? b1 = ctx.Books.FirstOrDefault(b => b.Title == "数学之美"); if (b1 != null) { b1.AuthorName = "张三"; } await ctx.SaveChangesAsync();
4. 删除
using efCore; using TestDbContext ctx = new TestDbContext(); Book? b1 = ctx.Books.FirstOrDefault(b => b.Title == "数学之美"); if (b1 != null) { ctx.Remove(b1); } await ctx.SaveChangesAsync();
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战