C# 实体框架灵活缓存
我正在寻找一个与Entity Framework 6+一起工作的缓存系统。要么找到合适的库,要么自己实现 我已经调查了这两个开源缓存提供程序: 实体框架6.1的二级缓存 EFSecondLevelCache 虽然我正在寻找一种方法来指定查询中的最大缓存时间,但它们看起来像是可靠的产品。我认为这是指定我能够接受的最旧数据的最佳方式(因为这当然非常依赖于业务逻辑) 我认为这是最好的称呼:C# 实体框架灵活缓存,c#,database,entity-framework,caching,entity-framework-6,C#,Database,Entity Framework,Caching,Entity Framework 6,我正在寻找一个与Entity Framework 6+一起工作的缓存系统。要么找到合适的库,要么自己实现 我已经调查了这两个开源缓存提供程序: 实体框架6.1的二级缓存 EFSecondLevelCache 虽然我正在寻找一种方法来指定查询中的最大缓存时间,但它们看起来像是可靠的产品。我认为这是指定我能够接受的最旧数据的最佳方式(因为这当然非常依赖于业务逻辑) 我认为这是最好的称呼: using (var db = new MyEF6Entities()) { var path =
using (var db = new MyEF6Entities()) {
var path = db.Configuration.Where(c => c.name="Path")
.AllowFromCache(TimeSpan.FromMinutes(60));
var onlineUserList = db.Users.Where(u => u.IsOnline)
.AllowFromCache(TimeSpan.FromSeconds(30));
}
有没有办法制作这样的API
EDIT:我现在已经按照@JonathanMagnan的建议尝试了EF+,但作为一个例子,下面的代码从未得到缓存命中。我知道这一点是因为它非常慢,我在mysql管理员中也看到与特定查询建立了连接,如果我更改数据库中的数据,它将立即显示,我预计会延迟60分钟
编辑2:我意识到缓存不起作用,但它仍然会创建到数据库的连接,因为我创建了一个新的上下文实例。然而,有一个问题!我在web服务中执行EF请求。根据web服务主机的主机名,将查询不同的数据库。EF Plus似乎无法处理这一问题,因此如果我以后使用,我将从中获得相同且不正确的结果。有没有办法用主机名标记缓存?
免责声明:我是项目的所有者 我不能代表您已经调查过的其他库,但EF+查询缓存允许在特定时间内缓存数据 维基: 范例 如果某些逻辑需要实时数据,而其他逻辑不需要,您还可以使用缓存“标记”多次缓存数据 范例 据我所知,我认为任何缓存支持都不会在最后X秒内获取缓存的数据 编辑:回答子问题
谢谢你,乔纳森。EF+如何使用不同的数据库来 例如,以及不同的登录用户。它能应付吗 这是自动的还是我需要给它一些提示 这取决于每个功能。例如,查询缓存与所有数据库提供程序一起工作,因为在引擎盖下只使用LINQ。您不需要指定任何内容,它已经处理了所有内容 其他一些功能,如QueryFuture,还不能在所有提供者上运行。它适用于流行的提供商,如SQL Server、SQL Azure和MySQL 您可以在每个功能下看到“需求”部分。如果它支持所有提供者,我们通常会说“所有受支持” 编辑:回答子问题 我在MyEF6Entities构造函数中更改了数据库,所以问题是 如果EF+将考虑数据库名称,或者这可能会造成混乱 在缓存中 从v1.3.34开始,连接字符串现在是键的一部分。因此,这将支持这种情况 密钥由以下部分组成:
- 缓存前缀
- 连接字符串
- 所有缓存标记
- 所有参数名称和值
var host1 = "http://host1/ClientConfig";
var host2 = "http://host2/ClientConfig";
var clientHost1 = db.ClientConfig.FromCache(DateTime.Now.AddMinutes(60), host1).ToList();
var clientHost1 = db.ClientConfig.FromCache(DateTime.Now.AddMinutes(60), host2).ToList();
所有标记都是缓存键的一部分,因此两个查询都将缓存在不同的缓存项中
编辑:回答子问题
我在MyEF6Entities()构造函数中设置了ConnectionString,然后
似乎仍然混淆了来自不同数据库的数据
能否生成缓存密钥并检查是否包含连接字符串
var query = b.Users.Where(u => u.IsOnline);
var cacheKey = QueryCacheManager.GetCacheKey(query, new string[0]);
如果我使用var clientHost,它就会起作用=
db.ClientConfig.FromCache(DateTime.Now.AddMinutes(60),
主机名);但是我不应该因为这个
连接字符串是不同的,对吗
是的,你说得对。如果连接字符串随主机而更改,则不需要它。谢谢。EF+如何使用不同的数据库,例如不同的登录用户。它会自动处理还是我需要给它一些提示?谢谢你的澄清,但不幸的是你误解了我,因为我不是很清楚。我不是说不同的数据库系统。我只在这个项目中使用MySQL。但是,我有多个MySQL数据库服务器,每个服务器中有多个MySQL数据库。我在MyEF6Entities构造函数中更改了数据库,所以问题是EF+是否会考虑数据库名称,或者这是否会破坏缓存?我现在尝试了EF+,但缓存无法正常工作。请看我原始问题的更新。今天晚些时候我将发布一个新版本,允许在库中使用内部逻辑的多个数据库,发布后我将回答您的问题。太棒了!期待发布!
using (var db = new MyEF6Entities()) {
var recentUserList = db.Users.Where(u => u.IsOnline)
.FromCache(DateTime.Now.AddHours(1), "recent");
var onlineUserList = db.Users.Where(u => u.IsOnline)
.FromCache(DateTime.Now.AddSeconds(30), "online");
}
var host1 = "http://host1/ClientConfig";
var host2 = "http://host2/ClientConfig";
var clientHost1 = db.ClientConfig.FromCache(DateTime.Now.AddMinutes(60), host1).ToList();
var clientHost1 = db.ClientConfig.FromCache(DateTime.Now.AddMinutes(60), host2).ToList();
var query = b.Users.Where(u => u.IsOnline);
var cacheKey = QueryCacheManager.GetCacheKey(query, new string[0]);