数据访问 - EntityFramework集成
前言
Masa提供了基于EntityFramework的数据集成,并提供了数据过滤与软删除的功能,下面我们将介绍如何使用它?
MasaDbContext入门
- 安装.Net 6.0
新建ASP.NET Core 空项目
Assignment.MasaEntityFramework,并安装Masa.Contrib.Data.EntityFrameworkCore、Swashbuckle.AspNetCore、Microsoft.EntityFrameworkCore.InMemory、Microsoft.EntityFrameworkCore.Toolsdotnet 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创建数据库新建类
Userpublic 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.cspublic 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可不添加,使用Swagger仅仅是为了测试调用服务,使用Postman或其他的Http工具也可以
修改
Program.cs,添加用户上下文(重点)builder.Services.AddMasaDbContext<UserDbContext>(options =>
{
options.Builder = (_, dbContextOptionsBuilder) => dbContextOptionsBuilder.UseInMemoryDatabase("test")
});
修改
Program.cs,使项目支持CodeFirstapp.MigrateDbContext<UserDbContext>((context, services) =>
{
});
不需要CodeFirst,不支持代码生成数据库可不添加
测试
MasaDbContext,修改Program.csapp.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.EFdotnet 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方法获取所有的用户列表,并取出任意一条id信息,然后再调用delete方法删除用户,最后再调用list方法,查看取出的id是否存在,以此来验证软删除是否有效。
如何临时禁用软删除过滤
默认查询中会将标记已经被删除的数据过滤不再进行查询,但也有一些场景需要查询所有的数据,此时就需要用到数据过滤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.InMemorydotnet 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方法,验证当前数据库是testapp.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节点读取数据库连接字符串
}
}
- 除了从配置文件中获取,还支持从其他地方获取数据库连接字符串吗?
目前有两种办法可以更改数据库连接字符串。
方法1: 修改Program.cs,并删除appsettings.json数据库连接字符串的配置
修改
Program.csbuilder.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

方法2: 重写IConnectionStringProvider和IDbConnectionStringProvider的实现并添加到DI中
新建类
CustomizeConnectionStringProviderpublic class CustomizeConnectionStringProvider : IConnectionStringProvider
{
public Task<string> GetConnectionStringAsync(string name = "DefaultConnection") => Task.FromResult (GetConnectionString(name)); public string GetConnectionString(string name = "DefaultConnection") => "test3";
}
新建类
CustomizeDbConnectionStringProviderpublic class CustomizeDbConnectionStringProvider : IDbConnectionStringProvider
{
public List<MasaDbContextConfigurationOptions> DbContextOptionsList { get; } = new()
{
new MasaDbContextConfigurationOptions("test3")
};
}
修改
Program.csbuilder.Services.AddSingleton<IConnectionStringProvider,CustomizeConnectionStringProvider>();
builder.Services.AddSingleton<IDbConnectionStringProvider,CustomizeDbConnectionStringProvider>();
调用
database方法,验证当前数据库是否为test3

总结
本篇文章主要讲解了MasaDbContext的基本用法以及软删除、数据过滤如何使用,下篇文章我们会讲解一下MasaDbContext是如何实现软删除、数据过滤的,以及本篇文章中提到使用数据库时不指定数据库链接字符串时如何实现的
本章源码
Assignment05
https://github.com/zhenlei520/MasaFramework.Practice
开源地址
MASA.BuildingBlocks:https://github.com/masastack/MASA.BuildingBlocks
MASA.Contrib:https://github.com/masastack/MASA.Contrib
MASA.Utils:https://github.com/masastack/MASA.Utils
MASA.EShop:https://github.com/masalabs/MASA.EShop
MASA.Blazor:https://github.com/BlazorComponent/MASA.Blazor
如果你对我们的 MASA Framework 感兴趣,无论是代码贡献、使用、提 Issue,欢迎联系我们

数据访问 - EntityFramework集成的更多相关文章
- Java Web学习系列——Maven Web项目中集成使用Spring、MyBatis实现对MySQL的数据访问
本篇内容还是建立在上一篇Java Web学习系列——Maven Web项目中集成使用Spring基础之上,对之前的Maven Web项目进行升级改造,实现对MySQL的数据访问. 添加依赖Jar包 这 ...
- ABP官方文档翻译 9.1 EntityFramework集成
EntityFramework集成 Nuget包 DbContext 仓储 默认仓储 自定义仓储 应用特定的基础仓储类 自定义仓储示例 仓储最佳实践 事务管理 数据存储 ABP可以使用ORM框架,它内 ...
- ABP文档 - EntityFramework 集成
文档目录 本节内容: Nuget 包 DbContext 仓储 默认仓储 自定义仓储 特定的仓储基类 自定义仓储示例 仓储最佳实践 ABP可使用任何ORM框架,它已经内置了EntityFrame(以下 ...
- ABP理论学习之EntityFramework集成
返回总目录 本篇目录 Nuget包 创建DbContext 仓储 仓储基类 实现仓储 自定义仓储方法 阅读其他 ABP可以使用任何ORM框架工作,并且已经内置了EntityFramework集成.这篇 ...
- 在 ASP.NET 中创建数据访问和业务逻辑层(转)
.NET Framework 4 当在 ASP.NET 中处理数据时,可从使用通用软件模式中受益.其中一种模式是将数据访问代码与控制数据访问或提供其他业务规则的业务逻辑代码分开.在此模式中,这两个层均 ...
- 测试 ClownFish、CYQ、Entity Framework、Moon、MySoft、NHibernate、PDF、XCode数据访问组件性能
下期预告: 由于很多园友反馈,有的组件不应该缺席.测试复杂度不够.测试还缺乏一定的公平. 因此考虑在下一个版本中,确保在更加公平的前提下进行更高复杂度的测试 . 同时将分为2组测试,纯SQL组件及纯O ...
- Yii的学习(2)--数据访问对象 (DAO)
摘自Yii官网:http://www.yiiframework.com/doc/guide/1.1/zh_cn/database.dao Yii提供了强大的数据库编程支持.Yii数据访问对象(DAO) ...
- 数据访问层DAL(数据库访问抽象类DataProvider)
晒晒数据访问层DAL,看看你的项目数据访问层使用的是什么形式,数据访问性能比较 采用什么样的数据访问形式是软件编码很重要的一个环节,良好的数据访问形式不仅能够提搞代码的执行效率,协作能力,更重要的是对 ...
- 数据访问模式之Repository模式
数据访问模式之Repository模式 数据访问层无非就是对数据进行增删改查,其中增.删.改等我们可以抽象出来写一个公共的接口或抽象类来定义这些方法,并采用一个基类实现这些方法,这样该基类派生的子 ...
随机推荐
- Pytorch 实现线性回归
Pytorch 实现线性回归 import torch from torch.utils import data from torch import nn # 合成数据 def synthetic_d ...
- 新华三Gen10服务器ILO 5 安装中文语言包
ILO 5 安装中文语言包 在官网下载语言包文件,并解压 选择firmware&OS software,点击右侧的update firmware 选择本地文件,浏览到语言包里面的lpk文件,点 ...
- 微信小程序绑定函数如何携带参数
一开始以为微信小程序的语法是和VUE的语法一样的,直接@click="click(field)",结果却不是这样的 在微信小程序中我们需要设置一个 data-set ,然后在绑定的 ...
- [笔记] Powerful Number 筛
定义 Powerful Number(以下简称 PN)筛类似于杜教筛,可以拿来求一些积性函数的前缀和. 要求: 假设现在要求积性函数 \(f\) 的前缀和 \(F(n)=\sum_{i=1}^nf(i ...
- 工程师姓什么很重要!别再叫我“X工”!!!
关注「开源Linux」,选择"设为星标" 回复「学习」,有我为您特别筛选的学习资料~ 工程师之间都是这么互相打招呼的-- "高工,你设计图通过了么?" &quo ...
- IIS发布Https和Https的问题
asp.net调试页面的时候遇到一个问题,我喜欢右键点击在浏览器查看页面,打开的页面默认是https的,其实iis会同时生成http和https两种页面,但是我懒得每次去点.问题是页面中测试接口是ht ...
- 百度3D离线地图开发,3D离线地图开发,百度地图离线开发
3D离线地图介绍(3D离线采用矢量数据作为地图基础,可保持地图数据最新) 一.开发中引用3D离线地图(可独立部署通过内外IP+端口进行访问,也可拷贝js库文件到项目中通过绝对路径访问) 1).离线AP ...
- 1903021121—刘明伟—Java第三周作业—学习在eclipse上创建并运行java程序
项目 内容 课程班级博客链接 19信计班(本) 作业要求链接 第三周作业 作业要求 每道题要有题目,代码,截图 扩展阅读 eclipse如何创建java程序 java语言基础(上) 扩展阅读心得: 想 ...
- [C++STL] 迭代器 iterator 的使用
定义 迭代器是一种检查容器内元素并遍历元素的数据类型,表现的像指针. 基本声明方式 容器::iterator it = v.begin();//例:vector<int>::iterato ...
- DCM:一个能够改善所有应用数据交互场景的中间件新秀
摘要:几乎所有涉及应用数据交互的场景都可以通过DCM来改善应用结构,提升开发与计算效率. 本文分享自华为云社区<DCM:中间件家族迎来新成员>,作者: 石臻臻的杂货铺. DCM是什么 现代 ...