当前位置:网站首页>5. 数据访问 - EntityFramework集成
5. 数据访问 - EntityFramework集成
2022-07-05 18:33:00 【InfoQ】
前言
Masa
EntityFramework
MasaDbContext入门
- 安装.Net 6.0
- 新建ASP.NET Core 空项目
Assignment.MasaEntityFramework
,并安装Masa.Contrib.Data.EntityFrameworkCore
、Swashbuckle.AspNetCore
、Microsoft.EntityFrameworkCore.InMemory
、Microsoft.EntityFrameworkCore.Tools
dotnet add package Masa.Contrib.Data.EntityFrameworkCore --version 0.4.0-rc.4
dotnet add package Swashbuckle.AspNetCore --version 6.2.3
dotnet add package Microsoft.EntityFrameworkCore.InMemory --version 6.0.5
dotnet add package Microsoft.EntityFrameworkCore.Tools --version 6.0.5
> 安装`Swashbuckle.AspNetCore`是为了方便通过`Swagger`来操作服务
> 安装`Microsoft.EntityFrameworkCore.InMemory`是为了方便,因此使用内存数据库,如果需要使用其他数据库,请自行安装对应的包
> 安装`Microsoft.EntityFrameworkCore.Tools`是为了使用CodeFirst创建数据库
- 新建类
User
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public uint Gender { get; set; }
public DateTime BirthDay { get; set; }
public DateTime CreationTime { get; set; }
public User()
{
this.CreationTime = DateTime.Now;
}
}
- 新建用户上下文
UserDbContext.cs
public class UserDbContext : MasaDbContext
{
public DbSet<User> User { get; set; }
public UserDbContext(MasaDbContextOptions options) : base(options)
{
}
}
> `UserDbContext`改为继承`MasaDbContext`, 并新增一个参数的构造函数,参数类型为`MasaDbContextOptions`
> 当项目中存在多个DbContext时,需要改为继承`MasaDbContext<TDbContext>`,构造函数参数类型改为`MasaDbContext<TDbContext>`
- 新建类
AddUserRequest
作为添加用户的参数
public class AddUserRequest
{
public string Name { get; set; }
public uint Gender { get; set; }
public DateTime BirthDay { get; set; }
}
- 新建类
HostExtensions
用于迁移数据库(使用CodeFirst)
public static class HostExtensions
{
public static void MigrateDbContext<TContext>(
this IHost host, Action<TContext, IServiceProvider> seeder) where TContext : DbContext
{
using (var scope = host.Services.CreateScope())
{
var services = scope.ServiceProvider;
var context = services.GetRequiredService<TContext>();
context.Database.EnsureCreated();
seeder(context, services);
}
}
}
- 修改
Program.cs
,新增Swagger
支持
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
app.UseSwagger();
app.UseSwaggerUI();
Swagger
Postman
- 修改
Program.cs
,添加用户上下文(重点)
builder.Services.AddMasaDbContext<UserDbContext>(options =>
{
options.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseInMemoryDatabase("test")
});
- 修改
Program.cs
,使项目支持CodeFirst
app.MigrateDbContext<UserDbContext>((context, services) =>
{
});
> 不需要CodeFirst,不支持代码生成数据库可不添加
- 测试
MasaDbContext
,修改Program.cs
app.MapPost("/add", (UserDbContext dbContext, [FromBody] AddUserRequest request) =>
{
dbContext.Set<User>().Add(new User()
{
Name = request.Name,
Gender = request.Gender,
BirthDay = request.BirthDay
});
dbContext.SaveChanges();
});
app.MapGet("/list", (UserDbContext dbContext) =>
{
return dbContext.Set<User>().ToList();
});
> 自行运行项目,执行`add`后创建一个新的用户,之后执行`list`得到一个以上的用户数据,则证明`MasaDbContext`使用无误
如何使用软删除
- 选中
Assignment.MasaEntityFramework
并安装Masa.Contrib.Data.Contracts.EF
dotnet add package Masa.Contrib.Data.Contracts.EF --version 0.4.0-rc.4
- 修改类
User
,并实现ISoftDelete
,代码改为:
public class User : ISoftDelete//重点:改为实现ISoftDelete
{
public int Id { get; set; }
public string Name { get; set; }
public uint Gender { get; set; }
public DateTime BirthDay { get; set; }
public DateTime CreationTime { get; set; }
public bool IsDeleted { get; private set; }
public User()
{
this.CreationTime = DateTime.Now;
}
}
> 增加实现`ISoftDelete`,并为`IsDeleted`属性添加set支持(可以是private set;)
- 修改
Program.cs
,并启用数据过滤
builder.Services.AddMasaDbContext<UserDbContext>(options =>
{
options.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseInMemoryDatabase("test");
options.UseFilter();//启用数据过滤,完整写法:options.UseFilter(filterOptions => filterOptions.EnableSoftDelete = true);
});
- 测试软删除是否成功
- 修改
Program.cs
,新增删除方法
app.MapDelete("/delete", (UserDbContext dbContext, int id) =>
{
var user = dbContext.Set<User>().First(u => u.Id == id);
dbContext.Set<User>().Remove(user);
dbContext.SaveChanges();
});
add
list
delete
list
如何临时禁用软删除过滤
IDataFilter
- 新增
All
方法用于查询所有的数据(包含标记已经删除的数据)
app.MapGet("/all", (UserDbContext dbContext, [FromServices] IDataFilter dataFilter) =>
{
//通过DI获取到IDataFilter,并调用其Disable方法可临时禁用ISoftDelete条件过滤
using (dataFilter.Disable<ISoftDelete>())
{
return dbContext.Set<User>().ToList();
}
});
- 重新运行项目,重复执行验证软删除步骤,确保通过
list
方法访问不到数据
- 重复运行验证软删除步骤的原因在于本示例使用的是内存数据库,项目停止后,所有数据都会被清空,重新执行是为了确保数据存在,仅被标记为删除
- 执行
all
方法,获取所有的数据,查看id所对应的用户数据是否存在
从配置文件中获取数据库连接字符串
- 选中项目
Assignment.MasaEntityFramework
,并安装Masa.Contrib.Data.EntityFrameworkCore.InMemory
dotnet add package Masa.Contrib.Data.EntityFrameworkCore.InMemory --version 0.4.0-rc.4
> 根据需要安装对应数据库包即可,如:`Masa.Contrib.Data.EntityFrameworkCore.SqlServer` (SqlServer)、`Masa.Contrib.Data.EntityFrameworkCore.Pomelo.MySql` (Pomelo提供的MySql)、`Masa.Contrib.Data.EntityFrameworkCore.Oracle` (Oracle)等
- 修改
Program.cs
,调整添加用户上下文配置为:
builder.Services.AddMasaDbContext<UserDbContext>(options => options.UseInMemoryDatabase().UseFilter());
- 修改
appsettings.json
,增加用户数据库连接字符串:
{
"ConnectionStrings": {
"DefaultConnection": "test"//更换为指定的数据库连接字符串
}
}
- 修改
Program.cs
,新增database
方法,验证当前数据库是test
app.MapGet("/database", (UserDbContext dbContext) =>
{
var field = typeof(MasaDbContext).GetField("Options", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic)!;
var masaDbContextOptions = field.GetValue(dbContext) as MasaDbContextOptions;
foreach (var dbContextOptionsExtension in masaDbContextOptions!.Extensions)
{
if (dbContextOptionsExtension is InMemoryOptionsExtension memoryOptionsExtension)
{
return memoryOptionsExtension.StoreName;
}
}
return "";
});
http://localhost:5002/database
常见问题
- 如何更改默认读取的配置节点?
- 修改用户上下文
UserDbContext
并增加ConnectionStringName
特性:
[ConnectionStringName("User")]//自定义节点名
public class UserDbContext : MasaDbContext
{
public DbSet<User> User { get; set; }
public UserDbContext(MasaDbContextOptions options) : base(options)
{
}
}
- 修改配置
appsettings.json
{
"ConnectionStrings": {
"User": "test"//改为从User节点读取数据库连接字符串
}
}
- 除了从配置文件中获取,还支持从其他地方获取数据库连接字符串吗?
Program.cs
appsettings.json
- 修改
Program.cs
builder.Services.Configure<MasaDbConnectionOptions>(option =>
{
option.ConnectionStrings = new ConnectionStrings(new List<KeyValuePair<string, string>>()
{
new("User", "test2")//其中键为节点名,与ConnectionStringName特性的Name值保持一致即可,如果未指定ConnectionStringName,则应该为DefaultConnection,值为数据库连接字符串
});
});
- 修改
appsettings.json
配置
// "ConnectionStrings": {
// "User": "test"
// },
- 调用
database
方法,验证当前数据库是否为test2
IConnectionStringProvider
IDbConnectionStringProvider
- 新建类
CustomizeConnectionStringProvider
public class CustomizeConnectionStringProvider : IConnectionStringProvider
{
public Task<string> GetConnectionStringAsync(string name = "DefaultConnection") => Task.FromResult (GetConnectionString(name));
public string GetConnectionString(string name = "DefaultConnection") => "test3";
}
- 新建类
CustomizeDbConnectionStringProvider
public class CustomizeDbConnectionStringProvider : IDbConnectionStringProvider
{
public List<MasaDbContextConfigurationOptions> DbContextOptionsList { get; } = new()
{
new MasaDbContextConfigurationOptions("test3")
};
}
- 修改
Program.cs
builder.Services.AddSingleton<IConnectionStringProvider,CustomizeConnectionStringProvider>();
builder.Services.AddSingleton<IDbConnectionStringProvider,CustomizeDbConnectionStringProvider>();
- 调用
database
方法,验证当前数据库是否为test3
总结
MasaDbContext
MasaDbContext
本章源码
开源地址
边栏推荐
猜你喜欢
Find in MySQL_ in_ Detailed explanation of set() function usage
记录Pytorch中的eval()和no_grad()
LeetCode 6109. 知道秘密的人数
MYSQL中 find_in_set() 函数用法详解
The 11th China cloud computing standards and Applications Conference | cloud computing national standards and white paper series release, and Huayun data fully participated in the preparation
Reading notes of Clickhouse principle analysis and Application Practice (5)
Copy the linked list with random pointer in the "Li Kou brush question plan"
如何获取飞机穿过雷达两端的坐标
Let more young people from Hong Kong and Macao know about Nansha's characteristic cultural and creative products! "Nansha kylin" officially appeared
【Autosar 十四 启动流程详解】
随机推荐
2022 latest Android interview written examination, an Android programmer's interview experience
深入底层C源码讲透Redis核心设计原理
Login and connect CDB and PDB
生词生词生词生词[2]
Idea configuring NPM startup
金太阳开户安全吗?万一免5开户能办理吗?
2022年阿里Android高级面试题分享,2022阿里手淘Android面试题目
How to obtain the coordinates of the aircraft passing through both ends of the radar
IDEA配置npm启动
[QNX Hypervisor 2.2用户手册]6.3.2 配置VM
vs2017 qt的各种坑
Use of websocket tool
爬虫01-爬虫基本原理讲解
Precautions for RTD temperature measurement of max31865 module
LeetCode 6109. 知道秘密的人数
2022 Alibaba Android advanced interview questions sharing, 2022 Alibaba hand Taobao Android interview questions
Use QT to traverse JSON documents and search sub objects
写作写作写作写作
关于服装ERP,你想知道的都在这里了
SAP 特征 特性 说明