我有一个包含多个输入的搜索表单 - 名字,姓氏,公司......
我想根据用户输入返回实体,或者如果没有输入任何内容,例如在姓氏字段中,则返回所有姓氏。
我相信我应该为此使用null-coalescing,就像t-sql中的“ISNULL”...
contacts = contacts.Where(s => s.firstname.ToUpper().Contains(fNameSearch.ToUpper() ?? *)
问题是我不知道如何在这种类型的预测中使用通配符。
例如,如果fNameSearch为null或white-space,则返回firstname属性中包含“test”的所有内容...
contacts = contacts.Where(s => s.firstname.ToUpper().Contains(fNameSearch.ToUpper() ?? "test")
但我希望能够归还所有东西,而不仅仅是“测试”。
答案 0 :(得分:8)
我相信我应该使用null-coalescing:
fNameSearch.ToUpper() ?? *
你的信念是错误的。只有在左侧可能为空时才使用??
才有意义。如果fNameSearch
为null,则调用ToUpper()
会抛出;如果它不为null,则对ToUpper()
的调用产生非空字符串。因此,??
运算符不是您想要使用的。
您正在寻找的运营商是提升的可空成员访问运营商:
fNameSearch.?ToUpper() ?? "test"
这意味着“如果fNameSearch
为null,则生成null,将其提供给??
运算符并获取"test"
;如果它不为null,则调用ToUpper()
,将产生非空字符串。
不幸的是,C#中不存在.?
运算符。这是一个经常被请求的功能,因此该语言的未来版本可能会有它。
但我希望能够归还所有东西,而不仅仅是“测试”。
然后你不想要任何一个算子。
退后一步。陈述你想要谓词的行为。
fNameSearch
为null,则匹配所有内容firstName.ToUpper().Contains(fnameSearch.ToUpper)
好的,这是一个容易编写的谓词。
s => fNameSearch == null || s.firstname.ToUpper().Contains(fNameSearch.ToUpper())
这段代码是否正确?
没有。 ToUpper
不是标准化名称的好方法。请记住,名称是文化工件</ em>,因此必须使用与名称相关联的文化的正确规则进行搜索。
执行此操作的正确方法是获取写入名称的区域性的CultureInfo
对象,然后调用
culture.CompareInfo.IndexOf(firstname, fNameSearch, CompareOptions.IgnoreCase)
并查看它是否带有有效索引。
此外,在编写更多试图规范化名称的代码之前,您可能应该阅读本文。
http://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/
答案 1 :(得分:6)
如果要返回所有内容,是否可以在查询之前放置条件?
var contacts = /* construct your original query here */
if (fNameSearch != null)
contacts = contacts.Where(s => s.firstname.ToUpper().Contains(fNameSearch.ToUpper());
编辑:根据Steve的评论,区分大小写取决于数据库的整理(并且是case-insensitive by default),因此您只需运行:
var contacts = /* construct your original query here */
if (fNameSearch != null)
contacts = contacts.Where(s => s.firstname.Contains(fNameSearch));
编辑 2 :如果您要检查多个输入,则可以使用相同的方法:
var contacts = /* construct your original query here */
if (string.IsNullOrEmpty(fNameSearch) == false))
contacts = contacts.Where(s => s.firstname.Contains(fNameSearch));
if (string.IsNullOrEmpty(fSurnameSearch) == false))
contacts = contacts.Where(s => s.surname.Contains(fSurnameSearch));
if (string.IsNullOrEmpty(fCompanySearch) == false))
contacts = contacts.Where(s => s.company.Contains(fCompanySearch));