如何使用其值将特定表达式,Func,Lambda序列化为字符串?

时间:2011-11-03 15:56:17

标签: caching lambda expression

我正在尝试使用此函数缓存查询:

public static string GenerateCacheKey(string className, string methodName, params object[] parameters)
    {
        string[] strings = parameters.Select(p => p==null ? "null" : p.ToString()).ToArray();
        return string.Format("{0}.{1}({2})", className, methodName, string.Join(",", strings));
    }

我有一个带有方法签名的存储库,如下所示:

IList<TEntity> List(int? page, int? pageSize,
                            Expression<Func<TEntity, bool>> predicate,
                            Expression<Func<TEntity, object>> sort);

对此的实际调用可能如下所示:

var activeItemsForUser =
                _itemRepository.List(null, null, 
i => i.Active && i.userId=userId, null).ToList();

问题在于为i =&gt; i.Active&amp;&amp; i.userId = userId为userId 123和userId 456生成的字符串缓存密钥是相同的。两者都只有字符串“value”代替userId值。

如何将实际表达式及其变量值序列化为每个表达式的唯一字符串,以便在我的GenerateCacheKey方法中使用?

2 个答案:

答案 0 :(得分:1)

这可能不太有帮助,但......

您可以制作规范类并将其用作缓存密钥吗?

public class ActiveUserSpec : ISpecification<User>
{
    int userId; 
    public ActiveUser(int userId){
       this.userId=userId;    
    }

    public Expression<Func<User, bool>> Match()
    {
        retuen u => u.Active && u.userId == userId;
    }
    public string AsString()
    {
        return GetType().ToString() + userId; 
    }
}

答案 1 :(得分:0)

序列化表达式树并不容易。基本上你需要某种类型的访问者来检查表达式的所有叶子并将它们转换为有意义的序列化。

.net中没有开箱即用的表达式树的序列化支持。

但你可以在这里找到一个很好的例子:

http://archive.msdn.microsoft.com/ExpressionSerializer

它序列化为XML。