.NETCore Entity Framework(ef)学这一篇就够了 - 基础知识(上篇)
一 概述
EF用途
Entity Framework (EF) Core 是轻量化、可扩展、开源和跨平台版数据库访问技术
作对象关系映射程序 (O/RM)
1. 能够使用 .NET 对象处理数据库(数据迁移,正式环境慎用)
备注:不建议使用数据迁移,需要学习处理数据库字段、长度、生成值(不生成、默认、添加或更新时生成)、键、索引等一定量内容,并且需要对数据库很熟悉,既然熟悉了数据库为什么还要在EF中处理呢,专业的任务还是专业的工具去做。
官方建议:部署到生产数据库的建议方法是生成 SQL 脚本
2. 无需编写大部分数据访问代码(sql)
二 DbContext上下文
生命周期
典型工作单元(ef使用涉及内容项)
- 创建实例-实例化上下文
- 根据上下文追踪实体实例
查询返回
添加到上下文 - 修改追踪的实体
- 保存到数据库(SaveChanges)
- 释放DbContext实例
注意事项
- 释放DbContext,防止内存泄漏
- 线程不安全,线程间杜绝共享上下文
实例化方式
ASP.NET Core依赖注入
- 创建上下文 - ApplicationDbContext
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
- StartUp.cs注册
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(
options => options.UseSqlServer("name=ConnectionStrings:DefaultConnection"));
}
- 控制器等使用 - MyController
public class MyController
{
private readonly ApplicationDbContext _context;
public MyController(ApplicationDbContext context)
{
_context = context;
}
}
New 初始化
数据库连接字符串
上下文中配置连接字符串
或则采用注入连接字符串
1.上下文中配置连接字符串 - ApplicationDbContext
public class ApplicationDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Test");
}
}
- 注入连接字符串
using var context = new ApplicationDbContext(@"Server=(localdb)\mssqllocaldb;Database=Test");
public class ApplicationDbContext : DbContext
{
private readonly string _connectionString;
public ApplicationDbContext(string connectionString)
{
_connectionString = connectionString;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(_connectionString);
}
}
DbContextOptions
var contextOptions = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Test")
.Options;
using var context = new ApplicationDbContext(contextOptions);
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
DbContextOptions说明
- DbContext起始点是DbContextOptionsBuilder,Builder生成DbContextOptions
- 获取方式
ASP.NET Core: AddDbContext等方法
DbContext中虚方法: OnConfiguring
配置数据库提供程序
上下文中配置连接字符串为例
public class ApplicationDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
//引用Nuget包Microsoft.EntityFrameworkCore.SqlServer
//optionsBuilder.UseSqlServer(@"Server=服务器;Database=数据库;User Id=用户名;Password=密码");
//引用Nuget包Npgsql.EntityFrameworkCore.PostgreSQL
optionsBuilder.UseNpgsql(@"Host=服务器;Port=端口;Database=数据库;User ID=用户名;Password=密码;Pooling=true;");
//引用Nuget包Pomelo.EntityFrameworkCore.MySql
//optionsBuilder.UseMySql(@"server=服务器;database=数据库;user id=用户名;password=密码;port=3306;");
//引用Nuget包Oracle.EntityFrameworkCore
//optionsBuilder.UseOracle(@"User Id=用户名;Password=密码;Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=服务器)(PORT=端口))(CONNECT_DATA=(SERVICE_NAME=数据库)))");
}
}
其他配置
查询追踪
跟踪与非跟踪单个实例
- 追踪
如果更改已追踪某个实例,SaveChanges会持久化到数据库(默认都会追踪) - 非追踪
- EF Core 3.0 之前
var blogs = context.Blogs
.AsNoTracking() //标记非追踪
.ToList(); - EF Core 5.0
建议使用AsNoTrackingWithIdentityResolution代替AsNoTracking
代替原因,性能优化。
3.0之前,已追踪的实例会被标识解析,如果是相同的实体,则每次返回相同实例。(使用更改追踪器)
非追踪的实例则不会标识解析,即使是相同的实体,也会返回新实例。
5.0,如果使用标识解析和非跟踪行为(即替换方案),后台使用独立的更改追踪器,每个实例具体化一次
OptionBuilder中配置默认值
//开启追踪,默认是TrackAll,可以显示声明
optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.TrackAll);
//请勿尝试,会禁止追踪所有实体
//optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
三 管理数据库架构
管理数据库架构其中一项工作是模型和数据库同步方式。
反向工程是将数据库转换为C#代码,当然通常做法是手动创建。
迁移模式不推荐使用,非要使用请参考官方文档:https://docs.microsoft.com/zh-cn/ef/core/managing-schemas/migrations/?tabs=dotnet-core-cli。在此不再累赘。
模型和数据库同步方式
- 迁移模式
以EF模型为准,修改模型后应用到数据库。即要熟悉数据库各技术要点,也要熟悉EF对应数据库要点的技术细节
- 反向工程
以数据库为准,通过数据库反向生成上下文和实体。仅熟悉数据库各技术要点
迁移模式
不做介绍
反向工程(.NET Core CLI)
1、安装工具
dotnet tool install --global dotnet-ef
2、安装设计依赖包
dotnet add package Microsoft.EntityFrameworkCore.Design
3、安装数据库提供程序
dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL
4、反向生成上下文和实体
dotnet ef dbcontext scaffold "User ID=postgres;Password=Bkggaq!@#123;Host=192.168.4.149;Port=5432;Database=bup_uom;Pooling=true;" Npgsql.EntityFrameworkCore.PostgreSQL
数据库表
生成的上下文和实体
5、删除上下文中OnModelCreating方法
该方法官方说明:
This method is called when the model for a derived context has been initialized, but before the model has been locked down and used to initialize the context. The default implementation of this method does nothing, but it can be overridden in a derived class such that the model can be further configured before it is locked down.
意思是上下文初始化后会调用该方法。采用反向工程不需要,则删除,避免不必要的麻烦。