Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过等式缓存LINQ表达式_C#_Linq_Caching - Fatal编程技术网

C# 通过等式缓存LINQ表达式

C# 通过等式缓存LINQ表达式,c#,linq,caching,C#,Linq,Caching,考虑一下这个场景 您有一个允许对其进行某些调用的存储库。这些调用使用LINQ,并且就返回的数据量而言可能相对昂贵 在我的例子中,如果数据是旧的,这并不太糟糕——可以实现一个缓存,这样就不会每次调用都执行大而昂贵的查询。嘿,我们甚至可以实现一些缓存策略来根据时间或使用情况确定何时再次执行该查询 我一直想弄清楚的是,如何在缓存中键入这些内容。一种方法是简单地说: "querytype1" = Particular LINQ expression "querytype2" = Particular L

考虑一下这个场景

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

在我的例子中,如果数据是旧的,这并不太糟糕——可以实现一个缓存,这样就不会每次调用都执行大而昂贵的查询。嘿,我们甚至可以实现一些缓存策略来根据时间或使用情况确定何时再次执行该查询

我一直想弄清楚的是,如何在缓存中键入这些内容。一种方法是简单地说:

"querytype1" = Particular LINQ expression
"querytype2" = Particular LINQ expression

然后用一个简单的字符串为缓存设置密钥。但是,考虑到我们正在进行LINQ,我们是否可以通过LINQ表达式本身为缓存设置密钥?我了解性能指标,但是否有必要比较两个LINQ表达式是否相同?

策略:比较SQL输出

一种策略可能是检索呈现的SQL text+参数,并确定它们是否与另一IQueryable中呈现的SQL+参数相同


有关更多信息,请参阅。

这是我目前的解决方案

鉴于此,在存储库中,我们将调用类似于:

public IEnumerable<MYPOCO> GetData(string someParameter, int anotherParameter);
然后,我为
字典
编写了一个扩展方法,基于。最后是一个
IEqualityComparer
类,它与
标准的类型一起工作

这意味着我的缓存现在由条件设置密钥,该条件是根据传递到存储库的参数设置的:

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>
公共类MyPocoRepository
{
private Cache _Cache=new Cache(CriteriaComparer);//传递给字典构造函数,它实际上就是缓存。
公共IEnumerable GetData(字符串someParameter,int-anotherParameter)
{
标准=新标准();
条件集(“someParameter”,someParameter)
.Set(“另一个参数”,另一个参数);
//我们现在可以基于此检查缓存。。。
}//eo GetData
}//eo MyPocoRepository

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

您如何比较LINQ表达式?对象是否实现了IComparable?@KyleC这是我的问题。是否有可能找出两个LINQ表达式在语义上是否相同(无论结果集如何),您可能希望查看懒惰类和模式:如果您查看我对其他问题的许多回答,当我询问性能含义时,会感到惊讶。唉,我们正在讨论的数据集可能非常大,
SELECT
语句本身也会非常大(唉,这会从多个第三方解决方案中获取信息,所以我无法真正将查询缩小)。这可能会将密钥置于“1kb+”的比较范围内。我认为,事实上,这将比重新询问更便宜(一个数量级)。我想我想知道我们是否可以散列LINQ表达式。你可以散列键并查找冲突。如果你想将实例作为键存储在
字典
@CharlesLambert中,你需要覆盖
Equals
GetHashCode
,这将教会我在写文章时不要把代码放在面前。请参见编辑,它是
IEqualityComparer
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>