9.2 数据库上下文
📝 模块更新日志
如果连接字符串是配置在自定义的 .json 文件中,那么必须在 Visual Studio 中配置 .json 右键属性,设置 复制 输出目录为 如果较新则复制,生成操作为:内容。
否则就会提示找不到配置或连接字符串的错误。
9.2.1 数据库上下文
简单来说,数据库上下文是负责和数据库交互的对象,提供程序对数据库存取提供了大量的方法。
在 Furion 框架中,默认集成了微软亲儿子:EntityFramework Core ,也就是通常数据库上下文指的是 DbContext 类或它的实现类。
9.2.2 AppDbContext
在我们实际项目开发过程中,使用 EFCore 提供的 DbContext 操作对象操作数据库有些繁琐和复杂,且默认不具备读写分离、多库等操作功能。
所以,Furion 框架提供了 AppDbContext<TDbContext, TDbContextLocator> 数据库上下文,该上下文继承自 DbContext。
后续章节,皆采用 EFCore 代替 EntityFramework Core。
9.2.3 AppDbContext 和 DbContext 区别
AppDbContext继承自DbContext,具备DbContext所有功能。AppDbContext支持多数据库操作泛型版本,如:AppDbContext<TDbContext, TDbContextLocator>AppDbContext自动配置实体信息,无需在OnModelCreating中配置AppDbContext支持内置多租户支持AppDbContext支持全局模型配置拦截器AppDbContext支持数据提交更改多个事件AppDbContext提供更加强大的模型操作能力,如Sql操作,读写分离等AppDbContext能够得到Furion框架更多的功能支持
9.2.4 如何定义数据库上下文
在 Furion 框架中了,提供了两种 AppDbContext 定义方式:
AppDbContext<TDbContext>操作默认数据库AppDbContext<TDbContext, TDbContextLocator>操作 N 个数据库
其中 AppDbContext<TDbContext> 默认继承自 AppDbContext<TDbContext, TDbContextLocator>。
下面是数据库上下文创建的多个例子:
9.2.4.1 创建默认数据库上下文
using Furion.DatabaseAccessor;
using Microsoft.EntityFrameworkCore;
namespace Furion.EntityFramework.Core
{
[AppDbContext("连接字符串或appsetting.json 键")]
public class FurionDbContext : AppDbContext<FurionDbContext> // 继承 AppDbContext<> 类
{
/// <summary>
/// 继承父类构造函数
/// </summary>
/// <param name="options"></param>
public FurionDbContext(DbContextOptions<FurionDbContext> options) : base(options)
{
}
}
}
9.2.4.2 创建其他数据库上下文
using Furion.DatabaseAccessor;
using Microsoft.EntityFrameworkCore;
namespace Furion.EntityFramework.Core
{
[AppDbContext("连接字符串或appsetting.json 键")]
public class FurOtherDbContext : AppDbContext<FurOtherDbContext, FurOtherDbContextLocator> // 继承 AppDbContext<> 类
{
/// <summary>
/// 继承父类构造函数
/// </summary>
/// <param name="options"></param>
public FurOtherDbContext(DbContextOptions<FurOtherDbContext> options) : base(options)
{
}
}
}
所有数据库上下文都应该在 Furion.EntityFramework.Core 项目中创建。另外如果系统用到了多个数据库,那么从第二个开始必须指定数据库上下文定位器。关于 TDbContextLocator 将在下一章节 《9.3 数据库上下文定位器》阐述。
9.2.5 配置连接字符串
Furion 框架提供多种数据库连接字符串配置方式:
- 在注册数据库服务时配置:
AddDbPool<TDbContext>("连接字符串")方式 - 使用
[AppDbContext("连接字符串/Key")]特性方式(只在AppDbContext 实现类有效)推荐 - 通过重写
OnConfiguring(DbContextOptionsBuilder optionsBuilder)配置
9.2.5.1 在注册数据库服务时配置
using Furion.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
namespace Furion.EntityFramework.Core
{
[AppStartup(600)]
public sealed class FurEntityFrameworkCoreStartup : AppStartup
{
public void ConfigureServices(IServiceCollection services)
{
// 配置数据库上下文,支持N个数据库
services.AddDatabaseAccessor(options =>
{
// 配置默认数据库
options.AddDbPool<FurionDbContext>(DbProvider.SqlServer, connectionMetadata:"连接字符串");
// 配置多个数据库,多个数据库必须指定数据库上下文定位器
options.AddDbPool<SqliteDbContext, SqliteDbContextLocaotr>(DbProvider.Sqlite, connectionMetadata:"连接字符串");
});
}
}
}
MySQL 在新版本包中注册有所修改,所以注册方式为:
services.AddDatabaseAccessor(options =>
{
options.AddDbPool<FurionDbContext>($"{DbProvider.MySql}@8.0.22");
});
9.2.5.2 [AppDbContext] 方式配置
using Furion.DatabaseAccessor;
using Microsoft.EntityFrameworkCore;
namespace Furion.EntityFramework.Core
{
[AppDbContext("DbConnectionString")] // 支持 `appsetting.json` 名或 连接字符串
public class FurionDbContext : AppDbContext<FurionDbContext>
{
/// <summary>
/// 继承父类构造函数
/// </summary>
/// <param name="options"></param>
public FurionDbContext(DbContextOptions<FurionDbContext> options) : base(options)
{
}
}
}
Furion 推荐使用此方式配置数据库连接字符串。
[AppDbContext] 内置属性:
ConnectionMetadata:支持数据库连接字符串,配置文件的ConnectionStrings中的Key或配置文件的完整的配置路径,如果是内存数据库,则为数据库名称。TablePrefix:当前数据库上下文表统一前缀TableSuffix:当前数据库上下文表统一后缀ProviderName:配置数据库提供器类型,传入DbProvider.XxxMode:配置数据库上下文模式,DbContextMode枚举类型,取值:Cached:缓存模型数据库上下文,默认值Dynamic:动态模型数据库上下文
SlaveDbContextLocators:主从库配置,设置多个从库定位器,Type[]类型UseSnakeCaseNaming:表名使用蛇形命名,bool类型,默认false,Furion 4.9.1.5+版本支持
9.2.5.3 OnConfiguring 方式配置
using Furion.DatabaseAccessor;
using Microsoft.EntityFrameworkCore;
namespace Furion.EntityFramework.Core
{
public class FurionDbContext : AppDbContext<FurionDbContext>
{
/// <summary>
/// 继承父类构造函数
/// </summary>
/// <param name="options"></param>
public FurionDbContext(DbContextOptions<FurionDbContext> options) : base(options)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
optionsBuilder.UseSqlServer("数据库连接字符串");
}
}
}
这三种方式可以同时使用,但是有优先级:[AppDbContext] -> 在注册数据库服务时配置 -> OnConfiguring(低到高)
也就是 OnConfiguring 配置会覆盖 在注册数据库服务时配置 配置,在注册数据库服务时配置 配置会覆盖 [AppDbContext] 配置所配置的连接字符串。