Linq”;全文“;搜索

本文关键字:搜索 全文 Linq | 更新日期: 2023-09-27 18:23:53

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

公共静态类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);
    }
}

Linq”;全文“;搜索

看起来,将exactMatch设置为true会有效果,因为它不会拆分搜索词。

FullTextSearch<MyType>(searchKey, true)

否则,请更改

orExpressions = Expression.Or(orExpressions,callContainsMethod);

andExpressions = Expression.And(andExpressions,callContainsMethod);