2011-09-15 30 views
2

對於question,答案表明我們不能使用LINQ to SQL或linq來實體。不區分大小寫動態搜索linq到實體

如果我寫

Expression toLower = Expression.Call(memberAccess, typeof(T).GetMethod("IndexOf", 
            new[] { typeof(T), typeof(StringComparison) })); 
    Expression condition = Expression.Call(toLower, 
           typeof(string).GetMethod("Contains"), 
           Expression.Constant(value.ToString().ToLower())); 
        lambda = Expression.Lambda(condition, parameter); 

我得到錯誤:

Value cannot be null. Parameter name: method 

如果我寫

Expression toLower = Expression.Call(memberAccess, typeof(string).GetMethod("IndexOf", 
             new[] { typeof(string), typeof(StringComparison) })); 

我得到的錯誤是:

Incorrect number of arguments supplied for call to method 'Int32 IndexOf(System.String, System.StringComparison)' 

在此先感謝

編輯: 這裏是片段,我需要能夠做到的情況下insenstivie過濾器:

public static IQueryable<T> Where<T>(this IQueryable<T> query, 
      string column, object value, WhereOperation operation) 
     { 
      if (string.IsNullOrEmpty(column)) 
       return query; 

      ParameterExpression parameter = Expression.Parameter(query.ElementType, "p"); 

      MemberExpression memberAccess = null; 
      foreach (var property in column.Split('.')) 
       memberAccess = MemberExpression.Property 
        (memberAccess ?? (parameter as Expression), property); 

      //change param value type 
      //necessary to getting bool from string 
      ConstantExpression filter = Expression.Constant 
       (
        Convert.ChangeType(value, memberAccess.Type) 
       ); 

      //switch operation 
      Expression condition = null; 
      LambdaExpression lambda = null; 
      switch (operation) 
      { 
       //equal == 
       case WhereOperation.Equal: 
        condition = Expression.Equal(memberAccess, filter); 
        lambda = Expression.Lambda(condition, parameter); 
        break; 
       //not equal != 
       case WhereOperation.NotEqual: 
        condition = Expression.NotEqual(memberAccess, filter); 
        lambda = Expression.Lambda(condition, parameter); 
        break; 
       //string.Contains() 
       case WhereOperation.Contains: 
        condition = Expression.Call(memberAccess, 
         typeof(string).GetMethod("Contains"), 
         Expression.Constant(value)); 
        lambda = Expression.Lambda(condition, parameter); 
        break; 
      } 


      MethodCallExpression result = Expression.Call(
        typeof(Queryable), "Where", 
        new[] { query.ElementType }, 
        query.Expression, 
        lambda); 

      return query.Provider.CreateQuery<T>(result); 
     } 

回答

3

修改代碼:

Expression toLower = Expression.Call(memberAccess, "ToLower", null, null);     
    lambda = Expression.Lambda(condition, parameter); 
2

你試圖調用IndexOf未指定任何參數。然後,您正在嘗試使用結果作爲Contains調用的目標,這是有些奇怪......我懷疑你真的想:

Expression indexOf = Expression.Call(memberAccess, "IndexOf", null, 
         Expression.Constant(value.ToString()), 
         Expression.Constant(StringComparison.OrdinalIgnoreCase)); 

Expression condition = Expression.NotEqual(indexOf, Expression.Constant(-1)); 

lambda = Expression.Lambda(condition, parameter); 

如果您能給我們介紹一下詳細信息,你想要什麼要實現 - 最好有一個簡短但完整的程序 - 這會更容易幫助你。

編輯:它將使在編譯時安全的方式使用Where,這樣更有意義:

Expression<Func<T, bool>> lambda = null; 

... 

lambda = Expression.Lambda<Func<T, bool>>(condition, parameter); 
return query.Where(lambda); 
+0

我加了碼,建議你給了,給編譯時錯誤。 – genericuser

+0

@ Priya10:我現在編輯了答案 - 我錯過了一個論點。但是,通過這種反射來調用「Where」是很奇怪的。編輯也是這樣... –

+0

我得到一個錯誤:LINQ to Entities無法識別方法'Int32 IndexOf(System.String,System.StringComparison)'方法,並且此方法無法轉換爲存儲表達式。 – genericuser