Linq“全文”搜索

时间:2013-07-19 16:00:43

标签: c# linq search full-text-search linq-expressions

我正在使用此搜索功能。但我需要它来做一个“和”而不是“或”我似乎无法让它返回我想要的结果。我需要执行搜索功能,搜索结果与框中输入的文本匹配。但只是部分搜索。例如,如果我输入“Super D”,我希望它能找到包含“Super”和“D”的所有内容。

public static class 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);
    }

}

1 个答案:

答案 0 :(得分:0)

看起来将设置exactMatch设置为true就可以解决问题,因为它不会将搜索项分开。

FullTextSearch<MyType>(searchKey, true)

如果失败,请更改

orExpressions = Expression.Or(orExpressions,callContainsMethod);

andExpressions = Expression.And(andExpressions,callContainsMethod);