通过相等缓存LINQ表达式

Moo*_*ice 6 c# linq caching

考虑这种情况.

您有一个存储库,允许对其进行某些调用.这些调用使用LINQ,并且就返回的数据量而言可能相对昂贵.

鉴于在我的情况下,如果数据是旧的并不是太糟糕 - 可以实现缓存,因此每次调用都不会执行大而昂贵的查询.嘿,我们甚至可以实现一些缓存策略来确定何时根据时间或用途再次执行该查询.

我试图解决的问题是如何在缓存中键入它.一种方法是简单地说:

"querytype1" = Particular LINQ expression
"querytype2" = Particular LINQ expression
Run Code Online (Sandbox Code Playgroud)

然后通过一个简单的字符串键入缓存.但是,鉴于我们正在使用LINQ,我们是否可以通过LINQ表达式本身来键入缓存?我理解性能指标,但无论如何要比较两个LINQ表达式是否相同?

Moo*_*ice 1

这是我目前的解决方案。

鉴于此,在存储库中,我们将进行类似以下的调用:

public IEnumerable<MYPOCO> GetData(string someParameter, int anotherParameter);
Run Code Online (Sandbox Code Playgroud)

因此我们可以说这些参数是标准。因此,我引入了一个Criteria类,它基本上包含Dictionary<string, object>实例,并具有一些类型安全的 setter 和 getter,简化了:

public class Criteria
{
    private Dictionary<string, object> _criteria = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);

    public Criteria Set<T>(string key, T value)
    {
        _criteria[key] = value;
        return this;
    } // eo Set

    public T Get<T>(string key)
    {
        return _criteria.ContainsKey(key) ? _criteria[key] : default(T);
    } // eo Get

    public Dictionary<string, object> Items { get { return _criteria; } }
}    // eo class Criteria
Run Code Online (Sandbox Code Playgroud)

然后,我Dictionary<TK, TV>根据这个 Stackoverflow 答案编写了一个扩展方法。最后,一个IEqualityComparer<Criteria>适用于Criteria.

这意味着我的缓存现在由标准键入,该标准是根据传入存储库的参数设置的:

public class MyPocoRepository<TMYPOCO>
{
    private Cache<Criteria, IEnumerable<TMYPOCO>> _cache = new Cache<Criteria, IEnumerable<TMYPOCO>>(CriteriaComparer); // is passed to the dictionary constructor which is actually the cache.
    public IEnumerable<TMYPOCO> GetData(string someParameter, int anotherParameter)
    {
        Criteria criteria = new Criteria();
        criteria.Set("someParameter", someParameter)
                .Set("anotherParameter", anotherParameter);
        // we can check the cache now based on this...
    } // eo GetData
} // eo MyPocoRepository<TMYPOCO>
Run Code Online (Sandbox Code Playgroud)

请注意,当我们想要参数完全相同的缓存策略,但可能有不同的用户帐户正在访问它时,这也允许我扩展这个想法(我们可以向条件添加一个字段,例如用户类型) ,即使 LINQ 表达式不会使用它)。