Caching 如何将特定表达式Func、Lambda序列化为带值的字符串?

Caching 如何将特定表达式Func、Lambda序列化为带值的字符串?,caching,lambda,expression,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.Forma

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

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();
问题是为userId 123和userId 456的i=>i.Active&&i.userId=userId生成的字符串缓存键是相同的。两者都只是用字符串“value”代替userId值


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

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

在.net中,表达式树开箱即用不支持序列化

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


它序列化为XML。

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

在.net中,表达式树开箱即用不支持序列化

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


它序列化为XML。

这可能不太有用,但

您可以创建一个规范类并将其用作缓存键

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; 
    }
}
公共类ActiveUserSpec:isSpecification
{
int用户标识;
public-ActiveUser(int-userId){
this.userId=userId;
}
公共表达式匹配()
{
retuen u=>u.Active&&u.userId==userId;
}
公共字符串AsString()
{
返回GetType().ToString()+用户ID;
}
}

这可能不太有用,但

您可以创建一个规范类并将其用作缓存键

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; 
    }
}
公共类ActiveUserSpec:isSpecification
{
int用户标识;
public-ActiveUser(int-userId){
this.userId=userId;
}
公共表达式匹配()
{
retuen u=>u.Active&&u.userId==userId;
}
公共字符串AsString()
{
返回GetType().ToString()+用户ID;
}
}

这就是我正在做的,尽管我在这里使用的是Jose的LinqSpecs项目:很好,LinqSpecs看起来相当不错。我正在使我的规范可组合,可以节省很多精力:)这就是我正在做的,尽管我在这里使用了Jose的LinqSpec项目:很好,LinqSpec看起来相当不错。我正在使我的规范可组合,这可以节省很多精力:)