出于性能考虑,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>(); ;
});