我已经在这条路上走过了几次,并且理解让它以这种方式工作的愿望,但根据我的经验,这是不可行的,或者如果是的话,不值得付出努力。原因是许多不同的存储引擎(包括内存缓存)具有无法轻松融入 EF 的差异。例如,一个简单的 DbSet 内存缓存实现可能不支持事务、延迟或急切加载方案等。我的想法是我希望能够在 Azure 表存储中进行交换。但是,排序、分页和查询不如 SQL Server 丰富。可以使用 SQL 执行的某些查询是 Azure 表无法执行的。最后,我总是回过头来相信,在 EF 背后更换持久性引擎的能力听起来很有吸引力,
如果我想支持缓存并且正在做一个 ASP.NET Web API,我会考虑使用 ASP.NET 缓存,以便在那时缓存 API 请求/响应。
如果我想支持不同的关系数据库供应商,我会使用第 3 方 EF 提供程序:各种数据库的实体框架提供程序列表顺便说一下,它们确实链接到缓存和跟踪 EF 提供程序——不知道这是否适用于较新的 EF。
如果我想在数据层或多个截然不同的存储引擎(即 Mongo、Azure 和 SQL)内进行缓存,我会在 EF 层“之上”进行缓存。像这样的东西:
public interface ISomeDataProvider
{
SomeType Find(int id);
....
}
public class EfDataProvider : ISomeDataProvider
{
private SomeAppDbContext db = new SomeAppDbContext();
public SomeType Find(int id){
return db.SomeTypes.Find(id);
}
}
public class AzureTableDataProvider : ISomeDataProvider
{
public SomeType Find(int id){
return //Azure Table code
}
}
public class CachingDataProvider : ISomeDataProvider
{
private ISomeDataProvider source;
private static IList<SomeType> cache = new List<SomeType>(); //List used here, but could use .NET Cache, Redis, etc.
public CachingDataProvider(ISomeDataProvider source){
this.source = source;
}
public SomeType Find(int id){
var result = cache.SingleOrDefault(x=>x.Id == id)
if(result == null){
result = source.SingleOrDefault(x=>x.Id == id)
if(result != null) cache.Add(result); //Again, trivial cache example. Cache expiration, refresh, loading, etc. should be considered per-app
}
return result
}
}
也就是说,对于我的大多数应用程序,当我想到它时,更换持久性引擎的能力并不是真正的要求。我的客户不“有些人想要 SQL,有些人想要 Azure Tables”。这可能只是由于我们所做的工作类型,但最终,它最终成为我只是接受并直接编码到 EF 的依赖项。