EFCore入门

概念

EF Core全称Entity Framework Core.EF Core主要以代码优先的方法为目标,很少支持数据库优先的方法,因为EF Core不支持可视化数据库模型设计器或向导

环境搭建

Nuget 包

管理Nuget包中添加项目所使用的数据库,大致名称为Microsoft.EntityFrameworkCore.xxx

实体类

创建与数据库表结构大致一样的实体类,举例存在T_Students表,表中有Id、姓名、年龄,这三个字段,那么创建以下实体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[Table("T_Students")] //自处标明表名,必须与数据库中表名保持一致
public class T_Students
{
public int Id { get; set; }

public string? Name { get; set; }

public int? age { get; set; }
}


public class MyDbContext : DbContext
{
public DbSet<T_Students> T_Students { get; set; }

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("连接字符串");
}
}

自动生成模型

微软官方提供了自动生成模型的方法,参考这里
以下步骤以VS用法为例
1.首先添加名为 Microsoft.EntityFrameworkCore.Design 的NuGet包
2.打开vs终端(工具-NuGet管理-控制台),输入:

1
Scaffold-DbContext '连接字符串' Microsoft.EntityFrameworkCore.SqlServer 

对于 SQL Server 或 Azure SQL,请使用 Microsoft.EntityFrameworkCore.SqlServer
Scaffold-DbContext
上面这种提示那么就是成功了
**注:步骤2在控制台中如果报错提示无法识别命令’Scaffold-DbContext’,添加

1
Microsoft.EntityFrameworkCore.Tools

NuGet包可解决**

数据操作

增加

在EfCore中保存有 SaveChanges()SaveChangesAsync() 两种方法
前者保存时是同步的,会阻塞当前线程,当有处理大量数据时候,可能会导致程序的性能问题,而后者是异步方法,会开启一个新的线程来做这些操作
使用await来等待异步操作执行完成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
static async Task Add()
{
//方法一
using (MyDbContext context = new MyDbContext())
{
context.Add(new T_Students { Name = "张三",age = 21 });
await context.SaveChangesAsync();
}

//方法二
MyDbContext context = new MyDbContext();
var s = new T_Students();
s.Name = "李四";
s.age = 22;
context.T_Students.Add(s);
await context.SaveChangesAsync();
}

删除、修改

EFCore的修改与删除都是先吧数据对象查询出来在进行操作,效率低,目前官方暂时没有支持高效的批量Update、Delete
有一个开源的批量修改删除项目可以参考Zack.EFCore.Batch
在EFCore 7中,微软官方已经开始支持批量修改以及批量删除的操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
static async Task GetList()
{
var context=new MyDbContext();
//EFCore7之后支持的新批量删除方法
await context.T_Students.Where(a => a.Id == 1).ExecuteDeleteAsync();

//在之前的版本中,只能用旧方法来删除
var s = context.T_Students.Where(a => a.Id == 1).FirstOrDefault();
context.T_Students.Remove(s);
await context.SaveChangesAsync();

//EFCore7之后支持的新批量修改方法
await context.T_Students.Where(a => a.Id==1).ExecuteUpdateAsync(a => a.SetProperty(aa => aa.Name, aa => "张三"));

//在之前的版本中,只能用旧方法来更新
var s2 = context.T_Students.Where(a => a.Id == 1).FirstOrDefault();
s2.Name = "王五";
await context.SaveChangesAsync();//修改


}

查询

DbSet有实现 IEnumberable 接口,因此可以使用Linq来更为方便的进行数据库操作,EFCore会将Linq转换为sql语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
static async Task GetList()
{
var context = new MyDbContext();

var SList1 = await context.T_Students.ToListAsync();//查询全部

var SList2 = await context.T_Students.Where(a => a.age < 22).ToListAsync();//查询年龄小于22岁的全部数据

var Student1 = context.T_Students.Where(a => a.Name == "张三").FirstOrDefault();//查询姓名为张三的单个对象

var SList4 = await context.T_Students.OrderByDescending(a => a.age).Skip(5).Take(3).ToListAsync();//根据年龄倒序排列后跳过前5条数据取前3条数据

var SList5 = context.T_Students.GroupBy(a => a.age).ToList().Select(a =>
{
var count = a.Count();
return new
{
a.Key, //age
count //当前年龄的人数
};
}).ToList();//根据年龄分组,投影出新的集合
}