自己造轮子是一件苦差事。 现在,您可以专注于业务开发,仅需集成 ⭐️Furion⭐️ 即可。
Skip to main content

9.2 数据库上下文定位器

小提醒

只要数据库上下文注册绑定了数据库上下文定位器,那么所有的仓储、实体、种子、配置、视图、函数等数据库相关的类、接口、方法都需要指定数据库上下文定位器,默认数据库上下文定位器除外。

如果改变了和数据库实体相关的所有配置接口的定位器,还需执行 Add-MigrationUpdate-Database 命令。

9.2.1 数据库上下文定位器

在了解数据库上下文定位器之前,我们先了解什么是 定位器定位器 就是给物体安装特殊配置,使其能够被实时追踪和定位。

那为什么需要 定位器

由于 EF Core 本身支持多个数据库上下文操作,但是通过 依赖注入 的方式默认只初始化一个数据库上下文,也就是如果我们想要操作多个数据库上下文,那么 构造函数 注入方式就会变得复杂。

所以,Furion 实现了一套 定位器 功能,通过这个 定位器 ,我们就能够通过 依赖注入 等多个方式定位到数据库上下文并初始化。

9.2.2 数据库上下文定位器作用

  • 能够实现构造函数初始化多个数据库上下文
  • 能够避免业务层直接引用 DbContext
  • 能够实现动态切换数据库、读写分离、主从库等复杂操作

9.2.3 如何定义数据库上下文定位器

定义数据库上下文定位器只需遵循三个原则即可:

  • 必须是公开 class 类型同时具备无参构造函数
  • 该类型必须继承 IDbContextLocator 接口
  • 数据库上下文定位器和数据库上下文必须是一对一关系,也就是不能同时被多个数据库上下文使用

数据库上下文定位器定义代码如下:

using Furion.DatabaseAccessor;

namespace Furion.Core
{
public sealed class FurionDbContextLocator : IDbContextLocator
{
}
}

9.2.4 默认数据库上下文定位器

Furion 框架中已经提供了 MasterDbContextLocator 默认数据库上下文定位器,所以默认数据库上下文只需继承 AppDbContext<TDbContext> 即可。

如:只有一个数据库上下文定义:

using Furion.DatabaseAccessor;
using Microsoft.EntityFrameworkCore;

namespace Furion.EntityFramework.Core
{
[AppDbContext("Sqlite3ConnectionString", DbProvider.Sqlite)]
public class DefaultDbContext : AppDbContext<DefaultDbContext> // 无需指定定位器
{
public DefaultDbContext(DbContextOptions<DefaultDbContext> options) : base(options)
{
}
}
}
关于多数据库定位器

默认数据库的定位器默认为 MasterDbContextLocator,所以无需显示指定定位器,但从第二个数据库开始,都必须指定数据库定位器。如:

  • 注册上下文:
options.AddDbPool<OtherDbContext, OtherDbContextLocator>();
  • 定义上下文
using Furion.DatabaseAccessor;
using Microsoft.EntityFrameworkCore;

namespace Furion.EntityFramework.Core
{
[AppDbContext("Sqlite3ConnectionString", DbProvider.Sqlite)]
public class OtherDbContext : AppDbContext<OtherDbContext, OtherDbContextLocator> // 需指定定位器
{
public OtherDbContext(DbContextOptions<OtherDbContext> options) : base(options)
{
}
}
}

另外,Entity/IEntityIRepository 等都需要指定定位器,如:IEntity<TKey, TLocator>IRepository<TEntity, TLocator> 操作。

9.2.5 数据库上下文定位器支持对象

目前数据库上下文支持以下多个对象:

  • AppDbContext<TEntity, TDbContextLocator>:数据上下文
  • IRepository<TEntity, TDbContextLocator>:实体仓储
  • ISqlRepository<TDbContextLocator>: Sql 操作仓储
  • IDbRepository<TDbContextLocator>: 特定数据库操作仓储
  • IMSRepository<TMasterDbContextLocator, TSlaveDbContextLocator1, ... TSlaveDbContextLocator7>: 读写分离仓储
  • Func<Type, DbContext>:依赖注入获取数据库上下文
  • Entity<Tkey, TDbContextLocator> :实体配置
  • EntityBase<Tkey, TDbContextLocator1, ... TDbContextLocator8>:实体配置
  • EntityNotKey<TDbContextLocator1, ... TDbContextLocator8>:无键实体配置
  • IEntity<TDbContextLocator1, ... TDbContextLocator8>:默认实体配置
  • IEntitySeedData<TEntity, TDbContextLocator1, ... TDbContextLocator8>:种子数据配置
  • IEntityTypeBuilder<TEntity, TDbContextLocator1, ... TDbContextLocator8>:实体类型构建器
  • IModelBuilderFilter<TDbContextLocator1, ... TDbContextLocator8>:模型构建筛选器
  • [QueryableFunction(DbContextLocators=Type[])]:查询函数

9.2.6 反馈与建议

与我们交流

给 Furion 提 Issue