我想找出一种方法来搜索用户的联系方式。
用户可以有多个联系人
下面是我的代码:_usersRep.Find(r=>(string.IsNullOrEmpty(vm.PhoneNumber)
|| r.UserContacts
.Select(o => o.TelephoneNo)
.Contains(vm.PhoneNumber))
这将返回给我的用户,它的任何联系人都包含我传递给它的PhoneNumber。我实际上试着找到它应该相等的地方,但我不能让它工作。
我已经在数据库中检查了这个用户有一个联系人对象,并且这个联系人对象的电话号码是我搜索的,但是它没有给我带来这个用户。
User
和UserContacts
的关系是一对多。
如果文本为空,我也想忽略搜索过滤器?但是当我不输入任何东西时,它会显示所有用户
我想你是在找这样的东西:
_usersRep.Where(r => r.UserContacts.Any(uc => uc.TelephoneNo == vm.PhoneNumber))
根据用户是否有匹配号码的任何用户联系人来限制返回哪些用户(Where子句)。
EDIT多重条件:
_usersRep.Where(r => r.UserContacts.Any(uc => uc.TelephoneNo == vm.PhoneNumber &&
uc.EmailAddress == vm.EmailAddress)) // etc
因此逻辑是,对于我们测试的每个UserContact,如果lambda表达式中的所有条件都为真,则它通过谓词,在这种情况下,我们使用Any测试,选择userRep。希望这是有意义的!
OK所以如果一些字段可以合法为空,我们应该确保过滤器是定义的,如果我们做比较,所以在一些嵌套的ORs
中组合在这里工作:
_usersRep.Where(r => r.UserContacts.Any(uc =>
(String.IsNullOrEmpty(vm.PhoneNumber) || uc.TelephoneNo == vm.PhoneNumber) &&
(String.IsNullOrEmpty(vm.EmailAddress) || uc.EmailAddress == vm.EmailAddress)))
注意,如果 vm中的所有字段都是空的,这将返回所有内容,因为没有限制。如果你不想要这个,你应该在调用这个查询之前检查。
只是为了说清楚这是如何工作的。如果我们为每个字段取基本子句:
(String.IsNullOrEmpty(vm.PhoneNumber) || uc.TelephoneNo == vm.PhoneNumber)
我们说如果部分A
或B
为真,那么对于这个字段我们有一个匹配。注意,||
运算符首先计算A
,只有在A
为假时才计算B
。所以,在简单的英语中,如果String.IsNullOrEmpty(vm.PhoneNumber)
是true
(即如果用户没有为这个字段输入查询文本),那么它是一个匹配,不管PhoneNumber
实际上是什么。所以我们只测试uc.TelephoneNo == vm.PhoneNumber
当vm.PhoneNumber
因此,上面的代码确定对于单个字段我们有一个匹配(要么是因为用户没有输入该字段的查询,要么因为他们输入了查询,并且字符串匹配)。现在我们使用&&
来确保我们检查的每个字段都是基于上述测试的匹配。
现在,因为我们首先对过滤器中的每个字段执行String.IsNullOrEmpty
,如果每个字段都为真,根据上述逻辑,所有内容都是匹配的。这在语义上也是有意义的——如果你不输入任何条件来限制搜索,你会期望收到所有的东西。
如果上面的问题在您的情况下,正如我之前所说的,我会在执行查询之前检查这一点,并告诉用户他们必须输入至少一个搜索词来限制搜索
当搜索字符串时您获得所有用户的原因是因为这个
_usersRep.Find(r=>(string.IsNullOrEmpty(vm.PhoneNumber) || ... )
如果电话号码字符串为null或空,则查找将始终返回true,给出所有用户
if(!string.IsNullOrEmpty(vm.PhoneNumber))
_usersRep.Find(r=> ... )
对于另一个问题,尝试修剪字符串
if(!string.IsNullOrEmpty(vm.PhoneNumber))
_usersRep.Find(r=>r.UserContacts
.Select(o => o.TelephoneNo)
.Contains(vm.PhoneNumber.Trim()))
除此之外,没有注意到任何其他应该给你带来问题的变化
假设vm.PhoneNumber
是您的搜索过滤器,将!
添加到String.IsNullOrEmpty
检查中,并将||
更改为&&
_usersRep.Find(r=>(!string.IsNullOrEmpty(vm.PhoneNumber)
&& r.UserContacts
.Select(o => o.TelephoneNo)
.Contains(vm.PhoneNumber))