当前位置:网站首页>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本章源码
开源地址

边栏推荐
- 7-2 保持链表有序
- Logical words in Articles
- vs2017 qt的各种坑
- What are the cache interfaces of nailing open platform applet API?
- FCN: Fully Convolutional Networks for Semantic Segmentation
- How much does the mlperf list weigh when AI is named?
- RPC protocol details
- Use of websocket tool
- sample_ What is the relationship between rate, sample and duration
- Einstein sum einsum
猜你喜欢
![Whether to take a duplicate subset with duplicate elements [how to take a subset? How to remove duplicates?]](/img/b2/d019c3f0b85a6c0d334a092fa6c23c.png)
Whether to take a duplicate subset with duplicate elements [how to take a subset? How to remove duplicates?]

AI金榜题名时,MLPerf榜单的份量究竟有多重?

A2L file parsing based on CAN bus (3)

node_ Exporter memory usage is not displayed

Isprs2022/ cloud detection: cloud detection with boundary nets

Rse2020/ cloud detection: accurate cloud detection of high-resolution remote sensing images based on weak supervision and deep learning

2022年阿里Android高级面试题分享,2022阿里手淘Android面试题目

集合处理的利器

Isprs2020/ cloud detection: transferring deep learning models for cloud detection between landsat-8 and proba-v

Take a look at semaphore, the current limiting tool provided by JUC
随机推荐
Clickhouse (03) how to install and deploy Clickhouse
使用JMeter录制脚本并调试
中文版Postman?功能真心强大!
What is the reason why the video cannot be played normally after the easycvr access device turns on the audio?
解决 contents have differences only in line separators
Fix vulnerability - mysql, ES
JDBC reads a large amount of data, resulting in memory overflow
vs2017 qt的各种坑
LeetCode 6109. 知道秘密的人数
@Extension, @spi annotation principle
输油管的布置数学建模matlab,输油管布置的数学模型
开户注册挖财安全吗?有没有风险的?靠谱吗?
线性表——抽象数据类型
Icml2022 | partial and asymmetric comparative learning of out of distribution detection in long tail recognition
7-1 链表也简单fina
【pm2详解】
Quickly generate IPA package
What are the cache interfaces of nailing open platform applet API?
Login and connect CDB and PDB
New words new words new words new words [2]
