Ef Core花里胡哨系列(5) 动态修改追踪的实体、动态查询

  • Ef Core花里胡哨系列(5) 动态修改追踪的实体、动态查询已关闭评论
  • 83 次浏览
  • A+
所属分类:.NET技术
摘要

同样还是IModelCacheKeyFactory,不过这次要采用主动刷新的方式。动态实体,根据配置等生成动态类型来当作数据库实体使用,当配置修改时,可以调用DynamicModelCacheKeyFactory.Refresh()刷新DbContext。


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.CoreMicrosoft.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)!;     } }