2013-02-12 55 views
1

我有我使用的泛型IQueryable列表LAMBDA - C# - 動態表情,使用string.IsNullOrEmpty

private static MethodInfo miTL = typeof(String).GetMethod("ToLower", Type.EmptyTypes); 

    public static IQueryable<T> Where<T>(IQueryable<T> source, string member, object value) 
    { 
     if (source == null) 
     { 
      throw new ArgumentNullException("source"); 
     } 
     if (member == null) 
     { 
      throw new ArgumentNullException("member"); 
     } 
     if (value == null) 
     { 
      throw new ArgumentNullException("value"); 
     } 

     if (value is string && !string.IsNullOrWhiteSpace(value.ToString())) 
     { 
      //If the type is string, force lowercase equals comparison for both sides. 
      value = value.ToString().ToLower(); 

      var parameter = Expression.Parameter(typeof(T), "item"); 
      var parameterProperty = Expression.Property(parameter, member); 

      //ToLower dynamic expression 
      var dynamicExpression = Expression.Call(parameterProperty, miTL); 

      var constantValue = Expression.Constant(value); 
      var equalsExpression = Expression.Equal(dynamicExpression, constantValue); 

      var lambdaExpression = Expression.Lambda<Func<T, bool>>(equalsExpression, parameter); 

      return source.Where(lambdaExpression); 
     } 
     else 
     { 
      var item = Expression.Parameter(typeof(T), "item"); 
      var prop = Expression.Property(item, member); 
      var soap = Expression.Constant(value); 
      var equal = Expression.Equal(prop, soap); 
      var lambda = Expression.Lambda<Func<T, bool>>(equal, item); 
      return source.Where(lambda); 
     } 
    } 

上進行一些動態過濾下面的代碼塊這一切工作正常 - 除了可能性我的源代碼包含空值,然後返回空引用異常。

它直接轉化爲(當字段是 「對手」: - {項=>(item.Counterparty.ToLower()== 「交易對手的名字」)}

我實際上需要在Lambda表達式形式是: -

{項目=> string.IsNullEmptyOrWhitespace(item.Counterparty)& &(item.Counterparty.ToLower()== 「交易對手的名稱」)!}

任何想法如何實現這一目標動態?

--REVIEWED--

這裏是整個替換代碼,使用好得多string.Equals檢查

public static IQueryable<T> Where<T>(IQueryable<T> source, string member, object value) 
    { 
     if (source == null) 
     { 
      throw new ArgumentNullException("source"); 
     } 
     if (member == null) 
     { 
      throw new ArgumentNullException("member"); 
     } 
     if (value == null) 
     { 
      throw new ArgumentNullException("value"); 
     } 

     if (value is string && !string.IsNullOrWhiteSpace(value.ToString())) 
     { 
      var parameter = Expression.Parameter(typeof(T), "item"); 
      var parameterProperty = Expression.Property(parameter, member); 

      var body = 
       Expression.AndAlso(
        Expression.Not(
         Expression.Call(typeof(string), "IsNullOrEmpty", null, parameterProperty) 
        ), 
        Expression.Call(typeof(string), "Equals", null, 
         parameterProperty, Expression.Constant(value), 
         Expression.Constant(System.StringComparison.InvariantCultureIgnoreCase)) 
       ); 

      var body2 = Expression.Call(typeof(string), "Equals", null, 
       parameterProperty, Expression.Constant(value), 
       Expression.Constant(System.StringComparison.InvariantCultureIgnoreCase)); 

      var lambdaExpression = Expression.Lambda<Func<T, bool>>(body, parameter); 

      return source.Where(lambdaExpression); 
     } 
     else 
     { 
      var item = Expression.Parameter(typeof(T), "item"); 
      var prop = Expression.Property(item, member); 
      var soap = Expression.Constant(value); 
      var equal = Expression.Equal(prop, soap); 
      var lambda = Expression.Lambda<Func<T, bool>>(equal, item); 
      return source.Where(lambda); 
     } 
    } 

回答

3

逐字翻譯會是這樣的:

var body = 
    Expression.AndAlso(
     Expression.Not(
      Expression.Call(typeof(string), "IsNullOrWhiteSpace", null, 
                 parameterProperty) 
     ), 
     Expression.Equal(
      Expression.Call(parameterProperty, "ToLower", null), 
      Expression.Constant("name of counterparty") 
     ) 
    ); 

但是,將很好地看看各種string.Equals重載。例如:

var body = Expression.Call(typeof(string), "Equals", null, 
    parameterProperty, Expression.Constant("name of counterparty"), 
    Expression.Constant(System.StringComparison.InvariantCultureIgnoreCase)); 
+0

嗨馬克,我寧願多使用類似string.IsNullEmptyOrWhitespace(item.Value)&& item.Value.Equals(otherLiteral,CurrentCulture.IgnoreCase) - 但我想不出出了一種這樣做的方式嗎? – 2013-02-12 08:46:54

+1

@ AdamO'Neil查看更新 – 2013-02-12 08:47:26

+0

輝煌 - 這比我的更好。非常感謝 – 2013-02-12 08:51:16