如何为EF实体类型实现(干净地)缓存?

时间:2011-09-13 20:12:17

标签: c# entity-framework

我一遍又一遍地反对这一点:编写代码来创建实体实例(即将行填充到数据库中),其中存在需要填充的子关联(即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))
                }
            };
        }
    }
}

期望:在给定的到期时间(例如10秒)model.Units.First(c => c.Name == "USD")执行的第一次执行,实体从数据库中获取,但随后(在有效期内)来自内存缓存。

目标:防止插入一百万行的循环使得相同的选择查询一百万次。

我特别感兴趣的是,这种非侵入式解决方案不会影响我在示例中编写代码的方式。这是(希望)本质上从建筑学角度分离关注点的最佳实践。

(ps:我不确定我使用非侵入性术语是否是标准语义 - 请告诉我是否有更好的方法来澄清这一点)

1 个答案:

答案 0 :(得分:0)

我不确定您的代码有什么意义,但它有明显的正确的解决方案:

    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 Caching Provider但是在这样的解决方案中,你的查询必须仍然被解析,哈希必须被计算等等。所以对于你的场景,将所有单位预加载到字典看起来更好的方式。 / p>