假设我有一个这样的课程:
class Person
{
string FirstName;
string MiddleName;
string LastName;
}
假设我有这样的样本数据:
William Henry Gates
Steven Paul Jobs
Mark Elliot Zuckerberg
然后,在Entity Framework / Linq中,我可以进行如下搜索:
string search = "paul";
search = search.ToUpper();
var people = db.People
.Where(p => p.FirstName.ToUpper().Contains(search)
.Where(p => p.MiddleName.ToUpper().Contains(search)
.Where(p => p.LastName.ToUpper().Contains(search);
这很有效。但是,如果用户搜索,例如:
search = "Henry Gates";
糟糕..理论上,(1)必须有效:
.Where(p => (p.FirstName +" "+ p.MiddleName +" "+ p.LastName).ToUpper().Contains(search);
或(2)必须有效:
.Where(p => (p.FirstName.ToUpper() +" "+ p.MiddleName.ToUpper() +" "+ p.LastName.ToUpper()).Contains(search);
并且有一个选项(3)我能想到:
.Select(p => new {FullName = p.FirstName +" "+ p.MiddleName +" "+ p.LastName)} )
.Where(p => p.FullName.Contains(search) )
最后,我的问题。在小表中,这不是那么相关,但在大表(如500k记录)中,它可能是一个问题,因为(在我的示例中)FirstName,MiddleName和LastName是索引字段,并且在每个字段中单独搜索很好,但是连接查询中的字段,SQL将执行全表扫描而不是使用索引,这使得简单的查询变得非常缓慢。
使用EntityFramework / Linq更复杂,因为我不确切知道将用于连接我的字段的标准是什么。
那么在连续列中搜索的方式是什么?
感谢您的帮助
答案 0 :(得分:1)
如果位置不相关,您可以先将输入字符串分解为List
,然后使用contains
查找匹配结果
// Define the search string
List<string> searchInput = new List<string> { "Paul", "Henry Gates", "Gates Henry" };
// Define the data
List<Person> persons = new List<Person>();
persons.Add(new Person() { FirstName = "William", MiddleName = "Henry", LastName = "Gates" });
persons.Add(new Person() { FirstName = "Steven", MiddleName = "Paul", LastName = "Jobs" });
persons.Add(new Person() { FirstName = "Mark", MiddleName = "Elliot", LastName = "Zuckerberg" });
// It may problem if you want to specific the field in sequence
persons.Add(new Person() { FirstName = "Henry", MiddleName = "Elliot", LastName = "Gates" });
// Another problem if a field contains all values
persons.Add(new Person() { FirstName = "Henry Gates", MiddleName = "Elliot", LastName = "Gates" });
// find the person
foreach (string input in searchInput)
{
List<string> inputList = input.Split(' ').Select(s => s.ToUpperInvariant()).ToList();
var qry = persons.Where(p => inputList.Contains(p.FirstName.ToUpperInvariant()) ||
inputList.Contains(p.MiddleName.ToUpperInvariant()) ||
inputList.Contains(p.LastName.ToUpperInvariant()));
var results = qry.ToList();
Console.WriteLine(string.Format("Search: {0} Found: {1}", input, results.Count));
foreach(var p in results)
{
Console.WriteLine(p.ToString());
}
Console.WriteLine();
}
结果如下:
Search: Paul Found: 1
First Name: Steven; Middle Name: Paul; Last Name: Jobs
Search: Henry Gates Found: 3
First Name: William; Middle Name: Henry; Last Name: Gates
First Name: Henry; Middle Name: Elliot; Last Name: Gates
First Name: Henry Gates; Middle Name: Elliot; Last Name: Gates
Search: Gates Henry Found: 3
First Name: William; Middle Name: Henry; Last Name: Gates
First Name: Henry; Middle Name: Elliot; Last Name: Gates
First Name: Henry Gates; Middle Name: Elliot; Last Name: Gates
希望这符合您的目的