CodeGo.net> WCF序列化谓词

我有一个WCF服务,它公开了一堆返回业务对象的方法.它的内部有一个漂亮的存储库层,它使用如下接口方法:

IEnumerable<User> GetUsers(Func<User, bool> predicate);

因此,如果我希望所有用户都属于给定角色,则可以这样做:

var plebs = GetUsers(u => u.Roles.Contains(plebRole));

现在,我想对WCF界面公开任何可以满足的过滤器思想. WCF api必须可供非.Net客户端访问,因此我想使用(相对)简单类型.

我有一个包含属性名称和值的Filter对象:

[DataContract] public class Filter {
    [DataMember] public string Property { get; set; }
    [DataMember] public string Value { get; set; }
}

所以现在我可以公开这样的WCF方法:

IEnumerable<User> GetUsers(IEnumerable<Filter> filters);

然后,我可以根据客户端过滤器中传入的内容构建谓词.现在变得凌乱:

private static Expression<Func<T, bool>> GetPredicate<T>(Filter filter)
{
  var knownPredicates = GetKnownPredicates<T>(filter.Value);
  var t = typeof(T);
  return knownPredicates.ContainsKey(t) && knownPredicates[t].ContainsKey(filter.Property)
           ? knownPredicates[t][filter.Property]
           : True<T>();
}

private static Dictionary<Type, Dictionary<string, Expression<Func<T, bool>>>> GetKnownPredicates<T>(string value)
{
  // ReSharper disable PossibleNullReferenceException
  return new Dictionary<Type, Dictionary<string, Expression<Func<T, bool>>>>
  {
    {
      typeof (User), new Dictionary<string, Expression<Func<T, bool>>>
      {
        { "Forename", x => (x as User).Forename == value },
        { "IsAdult", x => (x as User).IsAdult.ToString() == value },
        ...
      }
    },
    {
      typeof (Group), new Dictionary<string, Expression<Func<T, bool>>>
      {
        { "Name", x => (x as Group).Name == value },
        ...
      }
    },
    ...
  };
  // ReSharper restore PossibleNullReferenceException
}

在我开始编写GetKnownPredicates方法之前,代码并没有真正发臭.现在可以了.我如何解决它?

解决方法:

如果您想成为超级幻想者,可以使用System.Linq.Expressions.Expression类根据传入的过滤器动态构建谓词.您知道要搜索的类型,因此您所要做的就是使用Filter.Property和带有Filter.Value的常量表达式进行create a property expression的操作.使用它们来构成一个相等的表达式,您已经接近终点线.

习惯于编写表达式可能会很痛苦,但是调试器确实很有用,并且在编写表达式时会为您显示表达式的代码,因此请尝试一下!

上一篇:jdk8函数接口


下一篇:SpringData_03_Specifications动态查询