2013-07-19 95 views
0

我正在使用此搜索功能。但我需要它來做一個「和」不是「或」我似乎無法讓它返回我想要的結果。我需要在搜索結果與框中輸入的文本相匹配的情況下執行搜索功能。但只是部分搜索。例如,如果我輸入「超級D」,我希望它找到包含「超級」和「D」的所有內容。Linq「全文」搜索

公共靜態類ObjectContextExtensions {

public static IQueryable<T> FullTextSearch<T>(this IQueryable<T> queryable, string searchKey) 
    { 
     return FullTextSearch<T>(queryable, searchKey, false); 
    } 

    public static IQueryable<T> FullTextSearch<T>(this IQueryable<T> queryable, string searchKey, 
                bool exactMatch) 
    { 

     ParameterExpression parameter = Expression.Parameter(typeof(T), "c"); 
     MethodInfo containsMethod = typeof(string).GetMethod("Contains", new Type[] { typeof(string) }); 
     // MethodInfo toStringMethod = typeof (object).GetMethod("ToString", new Type[] {}); 


     var publicProperties = 
      typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) 
         .Where(p => p.PropertyType == typeof(string)); 
     Expression orExpressions = null; 
     string[] searchKeyParts; 

     if (searchKey == null) 
     { 
      searchKey = "0"; 
     } 
     searchKeyParts = !exactMatch ? searchKey.Split(' ') : new[] { searchKey }; 


     foreach (MethodCallExpression callContainsMethod in from property in publicProperties 
     select Expression.Property(parameter, property) into nameProperty 
     from searchKeyPart in searchKeyParts 

     let searchKeyExpression = Expression.Constant(searchKeyPart) let containsParamConverted = Expression.Convert(searchKeyExpression, typeof(string)) 

     select Expression.Call(nameProperty, containsMethod, (Expression)containsParamConverted)) 
     { 
      if (orExpressions == null) 
      { 
       orExpressions = callContainsMethod; 
      } 
      else 
      { 
       orExpressions = Expression.Or(orExpressions,callContainsMethod); 
      } 
     } 


     MethodCallExpression whereCallExpression = Expression.Call(
      typeof(Queryable), 
      "Where", 
      new Type[] { queryable.ElementType }, 
      queryable.Expression, 
      Expression.Lambda<Func<T, bool>>(orExpressions, new ParameterExpression[] { parameter })); 

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

} 
+0

有點亂? –

+0

你能告訴我一個例子嗎?我認爲這種方式將是模擬全文搜索的最佳方式 – user2600123

回答

0

看起來好像exactMatch設置爲true,會做的伎倆,因爲它不會拆分搜索字詞起來。

FullTextSearch<MyType>(searchKey, true) 

如果做不到這一點,你爲什麼不使用RegularExpressions改變

orExpressions = Expression.Or(orExpressions,callContainsMethod); 

andExpressions = Expression.And(andExpressions,callContainsMethod); 
+0

我試着將Expression.Or改爲Expression.And,但它不起作用。此外,如果我傳遞true,它不會拆分字符串,但我需要拆分字符串並搜索「stringa」和「stringb」而不是「stringa stringb」。我希望這是有道理的 – user2600123

+0

Expression.And爲我工作。什麼不適合你? – devlish

+0

當我使用Expression.And時,我的搜索結果中沒有返回任何內容。 – user2600123