我有以下内容,它查询我的集合上的属性以查找传递给该方法的查询中包含的任何潜在匹配项,查询可以包含空格:
var query = request.Query.ToLower().Trim();
if (query.Contains(" "))
{
var queryArr = query.Split(' ');
customers = queryArr.Aggregate(customers, FindCustomers);
}
else
{
customers = FindCustomers(customers, query);
}
FindCustomers看起来像这样:
private static IQueryable<Customer> FindCustomers(
IQueryable<Customer> customers, string query)
{
return customers.Where(
x =>
x.ACCOUNTNUM.ToLower().StartsWith(query) ||
x.NAME.ToLower().Contains(query) ||
x.ZIPCODE.ToLower().Contains(query) ||
x.CITY.ToLower().Contains(query));
}
这个问题是当用空格搜索时(例如:CUS0001 London TestAccount
),它似乎有点滞后所以想知道这是否是查询具有多个单词的对象中多个属性的最有效方法
在此之前访问数据库,我正在使用EF:
var customers = DbEntities.Customers.OrderBy(x => x.ACCOUNTNUM).AsQueryable();
答案 0 :(得分:1)
了解问题的方法之一是查看生成的查询 问题是你会有很多东西和ors:
SELECT ...
FROM ...
WHERE LOWER(ACCOUNTNUM) LIKE "query%"
OR LOWER(NAME) LIKE "%query%"
OR ...
OR LOWER(ACCOUNTNUM) LIKE "query2%"
OR LOWER(NAME) LIKE "%query2%"
...
它会很慢,因为文本搜索很慢。
优化的一种方法是使用大写而不是小写,因为大多数DBMS都针对大写比较优化:
var query = request.Query.ToUpper().Trim();
return customers.Where(
x =>
x.ACCOUNTNUM.ToUpper().StartsWith(query) ||
x.NAME.ToUpper().Contains(query) ||
x.ZIPCODE.ToUpper().Contains(query) ||
x.CITY.ToUpper().Contains(query));