如何(干净地)实现EF实体类型的缓存?
本文关键字:类型 实体 缓存 EF 实现 如何 | 更新日期: 2023-09-27 18:08:24
我一次又一次地遇到这种情况:编写代码来创建实体实例(即将行填充到数据库中),其中有需要填写的子关联(即FK引用)。
的例子:
namespace EomApp1.Formss.AB2.Model
{
public class UnitConversionSource : EomApp1.Formss.AB2.Model.IUnitConversionSource
{
IEnumerable<UnitConversion> IUnitConversionSource.UnitConversions(DirectAgentsEntities model)
{
yield return new UnitConversion
{
Coefficient = 1,
FromUnit = model.Units.First(c => c.Name == "USD"),
ToUnit = model.Units.First(c => c.Name == "USD"),
DateSpan = new DateSpan
{
FromDate = DateTime.Now,
ToDate = DateTime.Now.Add(TimeSpan.FromHours(1))
}
};
}
}
}
Desired:在给定的过期时间内(比如10秒)第一次执行model.Units.First(c => c.Name == "USD")
,实体从数据库中取出,但随后(在过期时间内)从内存缓存中取出。
目标:防止插入一百万行的循环执行相同的查询一百万次。
我特别感兴趣的是一个非侵入性的解决方案,它不会影响我在示例中编写代码的方式。这是(希望)从关注点分离体系结构的角度出发的最佳实践的精神。
(ps:我不确定我对"非侵入性"一词的使用是否符合标准语义——请告诉我是否有更好的表达方式)
我不知道你的代码是什么意思,但它有明显的和正确的解决方案:
IEnumerable<UnitConversion> IUnitConversionSource.UnitConversions(DirectAgentsEntities model)
{
string unit = model.Units.First(c => c.Name == "USD");
yield return new UnitConversion
{
Coefficient = 1,
FromUnit = unit,
ToUnit = unit,
DateSpan = new DateSpan
{
FromDate = DateTime.Now,
ToDate = DateTime.Now.Add(TimeSpan.FromHours(1))
}
};
}
如果你知道你必须经常使用一些值,正确的方法是将它们获取到一些字典中,并自己处理它的生存期,或者在一些缓存API中。
在更复杂的情况下,你可以使用EF缓存提供程序,但在这种解决方案中,你的查询仍然必须被解析,必须计算散列等,所以对于你的场景,将所有单元预加载到字典中看起来是更好的方法。