所以我有这个查询,如果查询中有一个匹配的单词,可以返回一个记录,其中包含名字,姓氏或电话号码:
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"姓氏是#34; Brian",如果我将查询作为" James Something"它应该返回一个记录。但它没有回归。我得到零记录。
答案 0 :(得分:1)
您的代码基本上过滤了所有“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;
}
}
答案 1 :(得分:1)
你得到"詹姆斯"在你的searchWords数组?你的代码似乎没问题。如果searchQuery包含像" James John Doe"那么searchWords的第一个元素就是"詹姆斯"其余的似乎很好。我已经厌倦了:
YES
我将User和Parent视为:
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)
);
}
在这种情况下,ParentObjects返回对象Ali John。
修改强> 要使用ParentObjects外部循环,请执行以下操作:
public class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Parent
{
public User Users { get; set; }
public Parent() { }
}
然后可以在循环外使用ParentObjects。
答案 2 :(得分:1)
使用foreach循环包装linq语句通常表示出现了问题。 Linq已经为你做了“循环”部分。
var searchWords = searchQuery
.Split(new char[]{' '}, StringSplitOptions.RemoveEmptyEntries)
.Select(x => x.Trim().ToUpper())
.ToArray();
在这里,我们将搜索逻辑反转为使用包含Any(),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);
答案 3 :(得分:0)
您还没有足够的资源来创建复制品,但如果我填写剩下的部分,您的现有代码似乎也能正常工作。
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