当前位置:网站首页>5. 数据访问 - EntityFramework集成
5. 数据访问 - EntityFramework集成
2022-07-05 18:33:00 【InfoQ】
前言
MasaEntityFrameworkMasaDbContext入门
- 安装.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();
SwaggerPostman- 修改
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();
});
addlistdeletelist如何临时禁用软删除过滤
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.csappsettings.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

IConnectionStringProviderIDbConnectionStringProvider- 新建类
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
总结
MasaDbContextMasaDbContext本章源码
开源地址

边栏推荐
- 怎么自动安装pythn三方库
- 线性表——抽象数据类型
- Notes on common management commands of openshift
- 什么是文本挖掘 ?「建议收藏」
- RPC protocol details
- Introduction to the development function of Hanlin Youshang system of Hansheng Youpin app
- sample_rate(采样率),sample(采样),duration(时长)是什么关系
- Is it complicated to open an account? Is online account opening safe?
- rust统计文件中单词出现的次数
- Fix vulnerability - mysql, ES
猜你喜欢

中文版Postman?功能真心强大!

Take a look at semaphore, the current limiting tool provided by JUC

AI open2022 | overview of recommendation systems based on heterogeneous information networks: concepts, methods, applications and resources

Use JMeter to record scripts and debug

【HCIA-cloud】【1】云计算的定义、什么是云计算、云计算的架构与技术说明、华为云计算产品、华为内存DDR配置工具说明

基于can总线的A2L文件解析(3)

深入底层C源码讲透Redis核心设计原理

MYSQL中 find_in_set() 函数用法详解

技术分享 | 接口测试价值与体系
![2022 latest intermediate and advanced Android interview questions, [principle + practice + Video + source code]](/img/c9/f4ab4578029cf043155a5811a64489.png)
2022 latest intermediate and advanced Android interview questions, [principle + practice + Video + source code]
随机推荐
ROS安装报错 sudo: rosdep:找不到命令
RPC protocol details
Various pits of vs2017 QT
【在優麒麟上使用Electron開發桌面應】
使用JMeter录制脚本并调试
How much does the mlperf list weigh when AI is named?
2022最新中高级Android面试题目,【原理+实战+视频+源码】
常见时间复杂度
Cronab log: how to record the output of my cron script
7-1 链表也简单fina
在通达信上做基金定投安全吗?
蚂蚁集团开源可信隐私计算框架「隐语」:开放、通用
2022 latest Android interview written examination, an Android programmer's interview experience
English sentence pattern reference
AI Open2022|基于异质信息网络的推荐系统综述:概念,方法,应用与资源
【在优麒麟上使用Electron开发桌面应】
RPC协议详解
C language makes it easy to add, delete, modify and check the linked list "suggested collection"
如何获取飞机穿过雷达两端的坐标
2022 Alibaba Android advanced interview questions sharing, 2022 Alibaba hand Taobao Android interview questions
