Ef Core花里胡哨系列(5) 動態修改追蹤的實體、動態查詢
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)!;
}
}

浙公網安備 33010602011771號