Ef Core花里胡哨系列(5) 动态修改追踪的实体、动态查询
1.Ef Core花里胡哨系列(2) 移除外键、扩展操作2.Ef Core花里胡哨系列(1) SafeDelete、ReadOnly、Audit 安全删除、只读、审计等3.Ef Core花里胡哨系列(3) 动态修改实体对应的表(分表)、多租户4.Ef Core花里胡哨系列(4) 多租户
5.Ef Core花里胡哨系列(5) 动态修改追踪的实体、动态查询
6.Ef Core花里胡哨系列(6) XML注释同步到数据库注释7.Ef Core花里胡哨系列(7) 使用Ef Core也能维护表架构?8.Ef Core花里胡哨系列(8) 如何可控管理Ef Core的迁移?9.Ef Core花里胡哨系列(9) 阴影属性,有用还是没用?10.Ef Core花里胡哨系列(10) 动态起来的 DbContext11.Ef Core花里胡哨系列(11) ef8 无实体查询,你好!Ef Core花里胡哨系列(5) 动态修改追踪的实体、动态查询
同样还是IModelCacheKeyFactory
,不过这次要采用主动刷新的方式。
实现DbContext
动态实体,根据配置等生成动态类型来当作数据库实体使用,当配置修改时,可以调用DynamicModelCacheKeyFactory.Refresh()
刷新DbContext。
动态构建部分不提供,我们将在其它的地方进行讨论。
public class SampleDbContext(DbContextOptions<SampleDbContext> options)
: DbContext(options)
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// 构建所有的FormType
FormTypeBuilderService.BuildFormTypes();
// 将Type添加到DbContext上下文
foreach (var type in FormTypeBuilderService.Value.GetModelTypes())
{
AddFormEntityType(type);
}
base.OnModelCreating(modelBuilder);
void AddFormEntityType(Type formType)
{
var entityType = modelBuilder.Model.FindEntityType(formType);
if (entityType == null)
{
modelBuilder.Model.AddEntityType(formType);
}
modelBuilder.Entity(formType).HasBaseType((Type)null!);
}
}
}
实现IModelCacheKeyFactory
我这里做了简化处理,直接检测了当前月份的变化,也可以通过实现一个静态变量由外部动态改变。
public class DynamicModelCacheKeyFactory : IModelCacheKeyFactory
{
private static Guid RefreshToken = Guid.NewGuid();
public static Guid Refresh() => Guid.NewGuid();
public object Create(DbContext context, bool designTime)
{
return DateTime.Now.ToString("yyyyMM");
}
}
替换DbContext
中的默认实现
services.AddDbContext<SampleDbContext>(opts =>
{
opts.ReplaceService<IModelCacheKeyFactory, DynamicModelCacheKeyFactory>();
});
派生DbContext
内置方法
实现一个DynamicSet
对标Set<T>
,需要安装System.Linq.Dynamic.Core
和Microsoft.EntityFrameworkCore.DynamicLinq
,即可使用lambda进行拼接查询。
public class SampleDbContext(DbContextOptions<SampleDbContext> options)
: DbContext(options)
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// 构建所有的FormType
FormTypeBuilderService.BuildFormTypes();
// 将Type添加到DbContext上下文
foreach (var type in FormTypeBuilderService.Value.GetModelTypes())
{
AddFormEntityType(type);
}
base.OnModelCreating(modelBuilder);
void AddFormEntityType(Type formType)
{
var entityType = modelBuilder.Model.FindEntityType(formType);
if (entityType == null)
{
modelBuilder.Model.AddEntityType(formType);
}
modelBuilder.Entity(formType).HasBaseType((Type)null!);
}
}
public IQueryable DynamicSet(string tableId)
{
var type = FormTypeBuilderService.GetModelType(tableId);
return (IQueryable)GetType().GetTypeInfo().GetMethod("Set", Type.EmptyTypes)!.MakeGenericMethod(type)
.Invoke(this, null)!;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?