c# – 将lambda表达式转换为用于缓存的唯一键

我看过其他与此相似的问题,但我找不到任何可行的答案.

我一直使用以下代码生成唯一的密钥,用于将我的LINQ查询的结果存储到缓存中.

string key = ((LambdaExpression)expression).Body.ToString();

    foreach (ParameterExpression param in expression.Parameters)
    {
        string name = param.Name;
        string typeName = param.Type.Name;

        key = key.Replace(name + ".",typeName + ".");
    }

    return key;

对于包含整数或布尔值的简单查询,似乎可以正常工作,但是当我的查询包含嵌套常量表达式

// Get all the crops on a farm where the slug matches the given slug.
(x => x.Crops.Any(y => slug == y.Slug) && x.Deleted == false)

所返回的关键是:

(True AndAlso (Farm.Crops.Any(y =>
(value(OzFarmGuide.Controllers.FarmController+<>c__DisplayClassd).slug
== y.Slug)) AndAlso (Farm.Deleted == False)))

正如你可以看到我通过的任何作物名称将给出相同的关键结果.有没有办法可以提取给定参数的值,以便区分我的查询

还要转换y来说正确的类型名称会很好…..

解决方法

正如Polity和Marc在他们的评论中所说的,你需要的是LINQ表达式的部分评估者.您可以在 Matt Warren’s LINQ: Building an IQueryable Provider – Part III中阅读使用 ExpressionVisitor方法.文章 Caching the results of LINQ queries by Pete Montgomery(由Polity链接)介绍了有关这种缓存的一些更多细节,例如如何在查询中表示集合.

另外,我不知道我会依靠这样的ToString().我认为这主要是为了调试目的,未来可能会改变.另一种方法是创建自己的IEqualityComparer< Expression>这可以为任何表达式创建一个哈希码,并且可以比较两个表达式的相等性.我也可能会使用ExpressionVisitor,但这样做将是相当乏味的.

相关文章

在项目中使用SharpZipLib压缩文件夹的时候,遇到如果目录较深,则压缩包中的文件夹同样比较深的问题。比...
项目需要,几十万张照片需要计算出每个照片的特征值(调用C++编写的DLL)。 业务流程:选择照片...
var array = new byte[4]; var i = Encoding.UTF8.GetBytes(100.ToString(&quot;x2&quot;));//...
其实很简单,因为Combox的Item是一个K/V的object,那么就可以把它的items转换成IEnumerable&lt;Dic...
把.net4.6安装包打包进安装程序。 关键脚本如下: 头部引用字符串对比库 !include &quot;WordFunc....
项目需求(Winform)可以批量打印某个模板,经过百度和摸索,使用iTextSharp+ZXing.NetʿreeSp...