2013-02-08 17 views
2

我正在形成如下所示的字符串表達式。像使用動態lambda表達式搜索日期時間字段

 string Condition = " it.person_id = " + personId.ToString(); 

    if (lstPersonFields != null) 
     { 
     foreach (var field in lstPersonFields) 
      {       
       string fieldCondition = " And it." + field.FieldName.ToString(); 
       if (field.FieldCondition == "Contains") 
        { 
        fieldCondition = fieldCondition + " Like '%" + field.FieldValue.ToString() + "%'"; 
        } 
       else if (field.FieldCondition == "Equals") 
        { 
        fieldCondition = fieldCondition + " = '" + field.FieldValue.ToString()+"'"; 
        } 
       Condition = Condition + fieldCondition; 
      } 
     } 
     var personSearch = FullPersonlst.Where(Condition).ToList(); 

上面的代碼像搜索正常工作超過datetime值等,並引發錯誤的日期時間字段,如

Like arguments must be of string type 

如何做到像搜索日期時間字段?

+0

你嘗試轉換成日期時間字符串..? – 2013-02-08 11:25:30

+0

我不認爲這是可能的,因爲我們沒有字段名稱。 – 2013-02-08 11:27:58

+0

請勿混淆輸入。重複:不要連接輸入。這是非常非常非常危險的代碼... – 2013-02-08 11:30:36

回答

1

要做到這一點作爲一個動態的Lambda表達式會是這樣的:

var arg = Expression.Parameter(typeof(Person), "it"); 
var body = Expression.Equal(
    Expression.PropertyOrField(arg, "PersonId"), 
    Expression.Constant(personId)); 

if (lstPersonFields != null) 
{ 
    foreach (var field in lstPersonFields) 
    { 
     var member = Expression.PropertyOrField(arg, field.FieldName); 
     switch (field.FieldCondition) 
     { 
      case "Contains": 
       body = Expression.AndAlso(body, 
        Expression.Call(typeof(SqlMethods), "Like", null, 
         member, 
         Expression.Constant("%" + field.FieldValue + "%"))); 
       break; 
      case "Equals": 
       body = Expression.AndAlso(body, 
        Expression.Equal(
         member, 
         Expression.Constant(field.FieldValue))); 
       break; 
     } 
    } 
} 
var lambda = Expression.Lambda<Func<Person,bool>>(body, arg); 
var personSearch = FullPersonlst.Where(lambda).ToList(); 
+0

當我將上面的代碼轉換爲LINQ to Entities時,它會拋出如下錯誤: LINQ to Entities不識別方法'Boolean Like(System.String,System.String)'方法,並且此方法無法轉換爲商店表達。 – 2013-02-08 12:15:38

+1

該版本('SqlMethods')是LINQ到SQL - 所以是它可能無法在EF中工作;你也可以使用'Contains' - 即'Expression.Call(member,「Contains」,null,Expression.Constant(field.FieldValue))',或者更多選項,請看這裏:http://stackoverflow.com/ question/1033007/like-operator-in-entity-framework – 2013-02-08 12:17:08

+0

@ Marc Gravell:上面的代碼不適用於datetime values.it,似乎需要對代碼進行一些更改。您可以告訴如何修改此代碼以使用datetime值。 – 2013-02-10 14:04:20

0

正如錯誤所述,您不應該使用非字符串值。這也沒有意義。如果您想搜索特定的日期時間,則使用datetime = value。用於搜索可以在兩者之間使用的時間範圍。您需要檢查要搜索的屬性的類型,並使用適當的方式來匹配查詢中的類型。

就我個人而言,我絕不會使用這樣的'動態查詢創建者'。