2017-02-15 158 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);