出于性能考慮喻圃,DbContext中的OnModelCreating在缺省狀態(tài)下泊愧,只在第一次實例化DbContext時執(zhí)行,執(zhí)行后的結果被放在緩存中官套,供以后的實例使用酒奶。然而,在有些情況下奶赔,DbContext需要根據(jù)調用的場景發(fā)生變化惋嚎,需要重新執(zhí)行OnModelCreating,這種情況下站刑,需要編寫自定義的緩存服務替換缺省的緩存服務另伍,新的緩存服務根據(jù)DbContext的變化確定緩存的鍵值,如果緩存中沒有相應的對象绞旅,就重新執(zhí)行OnModelCreating摆尝,生成相應的對象,保存在緩存中因悲。
首先堕汞,編寫自定義的ModelCacheKey,這里囤捻,我們需要為DynamicDbContext編寫ModelCacheKey臼朗,根據(jù)DynamicDbContext中的Key值確定ModelCacheKey是否變化:
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
namespace Plat.EFDynamic
{
class MyModelCacheKey : ModelCacheKey
{
private string key;
public MyModelCacheKey(DbContext context) : base(context)
{
key = (context as DynamicDbContext).Key;
}
protected override bool Equals(ModelCacheKey other)
=> base.Equals(other)
&& (other as MyModelCacheKey)?.key == key;
public override int GetHashCode()
{
var hashCode = base.GetHashCode() * 397;
if (!string.IsNullOrEmpty(key))
{
hashCode ^= key.GetHashCode();
}
return hashCode;
}
}
}
然后,編寫自定義的IModelCacheKeyFactory蝎土,根據(jù)DbContext創(chuàng)建ModelCacheKey:
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
namespace Plat.EFDynamic
{
public class MyModelCacheKeyFactory : IModelCacheKeyFactory
{
public object Create(DbContext context)
=> new MyModelCacheKey(context);
}
}
最后视哑,在定義DbContext時,使用自定義的IModelCacheKeyFactory替換缺省值:
services.AddEntityFrameworkSqlServer().AddDbContext<DynamicDbContext>(option =>
{
option.UseSqlServer(connstring)
.ReplaceService<IModelCacheKeyFactory, MyModelCacheKeyFactory>(); ;
});