出于性能考慮,DbContext中的OnModelCreating在缺省狀態下,只在第一次實例化DbContext時執行,執行后的結果被放在緩存中,供以后的實例使用。然而,在有些情況下,DbContext需要根據調用的場景發生變化,需要重新執行OnModelCreating,這種情況下,需要編寫自定義的緩存服務替換缺省的緩存服務,新的緩存服務根據DbContext的變化確定緩存的鍵值,如果緩存中沒有相應的對象,就重新執行OnModelCreating,生成相應的對象,保存在緩存中。
首先,編寫自定義的ModelCacheKey,這里,我們需要為DynamicDbContext編寫ModelCacheKey,根據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,根據DbContext創建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>(); ;
});