所以我有这个查询,如果查询中有一个匹配的单词与名字,姓氏或电话号码之一,它应该返回一条记录:
var searchWords = searchQuery
.Split(' ')
.Select(x => x.Trim()
.ToLower())
.Where(y => !string.IsNullOrWhiteSpace(y)).ToArray();
foreach (var searchWord in searchWords)
{
var word = searchWord;
someParentObjects= someParentObjects
.Where(x => x.User.FirstName.ToLower().Contains(word) ||
x.User.LastName.ToLower().Contains(word) ||
x.User.CellPhone.Contains(word)
);
}
不知何故包含匹配不工作,作为结果我得到零结果?为什么呢?
注意:第一部分工作得很好,我能够从searchQuery中获得修剪过的单词。
测试数据:基本上我要做的就是根据查询过滤结果。如果查询中有任何单词与名字、姓氏或手机中的任何一个匹配,我将返回这些记录。因此,如果我在我的数据库中有一个记录,其中名字是"James",姓氏是"Brian",如果我将查询传递为"James Something",它应该返回一个记录。但它并没有回归。我没有得到任何记录。
用foreach循环包装linq语句通常是出错的迹象。Linq已经在为你做"循环"部分了。
var searchWords = searchQuery
.Split(new char[]{' '}, StringSplitOptions.RemoveEmptyEntries)
.Select(x => x.Trim().ToUpper())
.ToArray();
在这里,我们将搜索逻辑反转为使用Any()中的contains, Linq将为我们处理枚举。
var result = (from step in patientSteps
where searchWords.Any(x =>
step.User.FirstName.ToUpper().Contains(x) ||
step.User.LastName.ToUpper().Contains(x) ||
step.User.CellPhone.Contains(x) )
select step);
您的代码实际上过滤了至少一个字段中存在的所有"searchWords"。对于多个单词,这样的过滤很可能没有返回结果。
搜索词"Bob John"和病人"John Doe"的简化版foreach
:
var filtered = new[]{"John"}
.Where(firstName => firstName.Contains("Bob"))
.Where(firstName => firstName.Contains("John"));
虽然不完全清楚您在寻找什么,但可能在第一个非空结果上停止是一个选项:
foreach (var searchWord in searchWords)
{
var word = searchWord;
var filteredPatientSteps = patientSteps
.Where(x => x.User.FirstName.ToLower().Contains(word) ||
x.User.LastName.ToLower().Contains(word) ||
x.User.CellPhone.Contains(word)
);
if (filteredPatientSteps.Any())
{
// jump out on first match
patientSteps = filteredPatientSteps;
break;
}
}
你在你的searchWords数组中得到"James"吗??你的代码似乎没问题。如果searchQuery包含像"James John Doe"这样的字符串,那么searchWords的第一个元素将是"James",其余的似乎没问题。我已经把它累成:
var searchQuery = "John Doe Brazil";
var searchWords = searchQuery
.Split(' ')
.Select(x => x.Trim()
.ToLower())
.Where(y => !string.IsNullOrWhiteSpace(y)).ToArray();
User obj=new User()
{
FirstName = "Ali",
LastName = "John"
};
var someParentObjects =new[]{ new Parent(){Users =obj}};
foreach (var searchWord in searchWords)
{
var word = searchWord;
var ParentObjects = someParentObjects
.Where(x => x.Users.FirstName.ToLower().Contains(word) ||
x.Users
.LastName.ToLower().Contains(word)
);
}
我将User和Parent设置为:
public class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Parent
{
public User Users { get; set; }
public Parent() { }
}
本例中的ParentObjects返回对象Ali John。
编辑:要在循环外使用ParentObjects,可以这样做:
List<Parent> ParentObjects=new List<Parent>();
foreach (var searchWord in searchWords)
{
var word = searchWord;
var ParentObject = someParentObjects.FirstOrDefault(x => x.Users.FirstName.ToLower().Contains(word) ||
x.Users
.LastName.ToLower().Contains(word));
if(ParentObject!=null)
ParentObjects.Add(ParentObject);
}
ParentObjects可以在循环之外使用。
您还没有提供足够的创建复制,但是如果我填充其余部分,您现有的代码似乎可以工作。
void Main() {
string searchQuery = "foo bar";
IEnumerable<PatientStep> patientSteps = new PatientStep[] {
new PatientStep("foo", "bar", "12345"),
new PatientStep("foo", "williams", "12345"),
new PatientStep("nancy", "bar", "12345"),
new PatientStep("nothing", "relevant", "12345"),
};
var searchWords = searchQuery
.Split(' ')
.Select(x => x.Trim()
.ToLower())
.Where(y => !string.IsNullOrWhiteSpace(y)).ToArray();
foreach (var searchWord in searchWords) {
var word = searchWord;
patientSteps = patientSteps.Where(
x => x.User.FirstName.ToLower().Contains(word)
|| x.User.LastName.ToLower().Contains(word)
|| x.User.CellPhone.Contains(word)
);
}
foreach (var patientStep in patientSteps) {
Console.WriteLine(patientStep.ToString());
}
}
class PatientStep {
public User User { get; private set; }
public PatientStep(string first, string last, string cell) {
this.User = new User { FirstName = first, LastName = last, CellPhone = cell };
}
public override string ToString() {
return string.Format("{0} {1}, {2}", this.User.FirstName, this.User.LastName, this.User.CellPhone);
}
}
class User {
public string FirstName { get; set; }
public string LastName { get; set; }
public string CellPhone { get; set; }
}
输出如下:
foo bar, 12345