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看起来相当不错。我正在使我的规范可组合,这可以节省很多精力:)