LINQ 查询的可选过滤器返回意外结果
Optional filters on LINQ Query returning unexpected result
我有一个功能可以搜索用户列表,包括用户名、用户地址、以前的地址和 phone 号码。
一旦我有了这些用户信息,我就可以根据他们的用户名、地址、以前的地址或 phone 号码进行过滤。
当我得到用户结果并过滤特定 phone 号码时,过滤器 returns 正确的 phone 号码和其他相关信息。
当我搜索没有 phone 号码的用户名时出现问题。所以当我搜索一个用户名,然后过滤一个特定的用户名时,结果是空的。
例如,如果我搜索用户名 "John",我会得到 100 个匹配该用户名的结果以及他们的用户地址、以前的地址和 phone 号码。
过滤 John123 没有任何问题。
但是,如果我搜索 "Mary",并尝试针对特定用户名进行过滤,我不会得到任何结果。这是因为所有带 "Mary" 的用户名都没有 phone 号码。
下面的代码是我试过的,但没有按预期工作。有人可以看一下并告诉我哪里错了吗?
var finalResult = context.User
.Select(x => new UserModel()
{
UserName = x.Name,
UserAddress = x.Address,
PreviousAddress = x.PAddress,
PhoneNumber = x.PhoneNumbers.Select(y => y.PersonalNumber),
}).AsQueryable();
if (!string.IsNullOrWhiteSpace(search.UserName))
{
finalResult = finalResult.Where(x => EF.Functions.Like(x.UserName, $"%{search.UserName}%"));
if (search.UserNameFilter != "" || search.PhoneNumberFilter != "")
{
finalResult = finalResult.Where(x =>
((EF.Functions.Like(x.PhoneNumber.FirstOrDefault(), $"%{search.PhoneNumberFilter}%")) &&
EF.Functions.Like(x.UserName, $"%{search.UserName}%") &&
EF.Functions.Like(x.UserName, $"%{search.UserNameFilter}%") &&
EF.Functions.Like(x.PreviousAddress, $"%{search.PreviousAddressFilter}%") &&
EF.Functions.Like(x.UserAddress, $"%{search.UserAddressFilter}%")));
return finalResult;
}
return finalResult;
}
拆分测试并分别用 if
保护每个过滤器:
var finalResult = context.User
.Select(x => new UserModel() {
UserName = x.Name,
UserAddress = x.Address,
PreviousAddress = x.PAddress,
PhoneNumber = x.PhoneNumbers.Select(y => y.PersonalNumber),
});
if (!String.IsNullOrWhiteSpace(search.UserName))
finalResult = finalResult.Where(x => EF.Functions.Like(x.UserName, $"%{search.UserName}%"));
if (search.UserNameFilter != "")
finalResult = finalResult.Where(x => EF.Functions.Like(x.UserName, $"%{search.UserNameFilter}%"));
if (search.PhoneNumberFilter != "")
finalResult = finalResult.Where(x => EF.Functions.Like(x.PhoneNumber.FirstOrDefault(), $"%{search.PhoneNumberFilter}%"));
if (search.PreviousAddressFilter != "")
finalResult = finalResult.Where(x => EF.Functions.Like(x.PreviousAddress, $"%{search.PreviousAddressFilter}%"));
if (search.UserAddressFilter != "")
finalResult = finalResult.Where(x => EF.Functions.Like(x.UserAddress, $"%{search.UserAddressFilter}%"));
return finalResult;
PS 不要在 IQueryable
上调用 AsQueryable
- 永远了解你的类型。
我有一个功能可以搜索用户列表,包括用户名、用户地址、以前的地址和 phone 号码。 一旦我有了这些用户信息,我就可以根据他们的用户名、地址、以前的地址或 phone 号码进行过滤。 当我得到用户结果并过滤特定 phone 号码时,过滤器 returns 正确的 phone 号码和其他相关信息。
当我搜索没有 phone 号码的用户名时出现问题。所以当我搜索一个用户名,然后过滤一个特定的用户名时,结果是空的。
例如,如果我搜索用户名 "John",我会得到 100 个匹配该用户名的结果以及他们的用户地址、以前的地址和 phone 号码。 过滤 John123 没有任何问题。
但是,如果我搜索 "Mary",并尝试针对特定用户名进行过滤,我不会得到任何结果。这是因为所有带 "Mary" 的用户名都没有 phone 号码。
下面的代码是我试过的,但没有按预期工作。有人可以看一下并告诉我哪里错了吗?
var finalResult = context.User
.Select(x => new UserModel()
{
UserName = x.Name,
UserAddress = x.Address,
PreviousAddress = x.PAddress,
PhoneNumber = x.PhoneNumbers.Select(y => y.PersonalNumber),
}).AsQueryable();
if (!string.IsNullOrWhiteSpace(search.UserName))
{
finalResult = finalResult.Where(x => EF.Functions.Like(x.UserName, $"%{search.UserName}%"));
if (search.UserNameFilter != "" || search.PhoneNumberFilter != "")
{
finalResult = finalResult.Where(x =>
((EF.Functions.Like(x.PhoneNumber.FirstOrDefault(), $"%{search.PhoneNumberFilter}%")) &&
EF.Functions.Like(x.UserName, $"%{search.UserName}%") &&
EF.Functions.Like(x.UserName, $"%{search.UserNameFilter}%") &&
EF.Functions.Like(x.PreviousAddress, $"%{search.PreviousAddressFilter}%") &&
EF.Functions.Like(x.UserAddress, $"%{search.UserAddressFilter}%")));
return finalResult;
}
return finalResult;
}
拆分测试并分别用 if
保护每个过滤器:
var finalResult = context.User
.Select(x => new UserModel() {
UserName = x.Name,
UserAddress = x.Address,
PreviousAddress = x.PAddress,
PhoneNumber = x.PhoneNumbers.Select(y => y.PersonalNumber),
});
if (!String.IsNullOrWhiteSpace(search.UserName))
finalResult = finalResult.Where(x => EF.Functions.Like(x.UserName, $"%{search.UserName}%"));
if (search.UserNameFilter != "")
finalResult = finalResult.Where(x => EF.Functions.Like(x.UserName, $"%{search.UserNameFilter}%"));
if (search.PhoneNumberFilter != "")
finalResult = finalResult.Where(x => EF.Functions.Like(x.PhoneNumber.FirstOrDefault(), $"%{search.PhoneNumberFilter}%"));
if (search.PreviousAddressFilter != "")
finalResult = finalResult.Where(x => EF.Functions.Like(x.PreviousAddress, $"%{search.PreviousAddressFilter}%"));
if (search.UserAddressFilter != "")
finalResult = finalResult.Where(x => EF.Functions.Like(x.UserAddress, $"%{search.UserAddressFilter}%"));
return finalResult;
PS 不要在 IQueryable
上调用 AsQueryable
- 永远了解你的类型。