2017-02-15 164 views
0

对于我的应用程序,我将一个'Filter'对象传递给具有属性名称和属性值的后端。基于属性字符串名称与ef进行动态比较

我发现下面的代码在互联网上做EF

public static IOrderedQueryable<T> Contains<T>(this IQueryable<T> queryable, string propertyName, string propertyValue) 
     { 
      var parameterExp = Expression.Parameter(typeof(T), "type"); 
      var propertyExp = Expression.Property(parameterExp, propertyName); 
      var method = typeof(string).GetMethod("Contains", new[] { typeof(string) }); 
      var someValue = Expression.Constant(propertyValue, typeof(string)); 
      var containsMethodExp = Expression.Call(propertyExp, method, someValue); 

      var expression = Expression.Lambda<Func<T, bool>>(containsMethodExp, parameterExp); 

      var expcall = Expression.Call(typeof(Queryable), "Where", new[] {typeof(T)}, queryable.Expression,Expression.Quote(expression)); 

      return (IOrderedQueryable<T>)queryable.Provider.CreateQuery<T>(expcall); 
     } 

我称之为像这样的动态包含:

query = query.Contains(filter.Property, (string)filter.Value); 

现在我试图找到一个相同比较要做到这一点:

query = query.Where(x => x.Status == filter.Value); 

x.Status是一个枚举这么

query = query.Where(x => x.Status.Equals(filter.Value)); 

抛出

无法创建类型的恒定值 'System.Object的'。在这种情况下,只支持原始类型或枚举类型

即使当我将它转换为int。

所以我需要做的“==”,而不是平等的,但我不知道如何建立一个方法,如包含一个没有方法名称,如包含还是equals

我想要什么,这样的事情:

query = query.IsTheSame(filter.Property, (Status)filter.Value); 
+1

请包括未使用的代码,并解释如何你知道它不工作(编译器错误?运行时异常?错误的结果?...?) – Richard

回答

0

==操作检查精确匹配,如果你使用的是等效的,但不同的对象,它们之间的==运营商将是错误的。 Equals在相似但不同的物体的情况下将是真实的。所以我想解决办法是

query = query.Where(x => (x.Status != null) && (x.Status.Equals(val))); 
0

所以我需要做的“==”,而不是平等的,但我不知道如何建立一个方法,如包含一个没有方法名称,如包含或等于

这实际上更容易得益于Expression.Equal方法。

下面是一个简单的实现(与奖金处理嵌套属性/字段):

public static IQueryable<T> WhereEquals<T>(this IQueryable<T> source, string memberPath, object value) 
{ 
    var parameter = Expression.Parameter(typeof(T), "e"); 
    var member = memberPath.Split('.').Aggregate((Expression)parameter, Expression.PropertyOrField); 
    var predicate = Expression.Lambda<Func<T, bool>>(
     Expression.Equal(member, Expression.Constant(value)), 
     parameter); 
    return source.Where(predicate); 
} 

,你这样调用:

query = query.WhereEquals(filter.Property, filter.Value);