使用Entity Framework在数据库中搜索文本

我正在编写一个UI,允许某人通过他们的名字和/或姓名查找用户。 例如,如果您输入“Mike”作为名字,输入“Jo”作为姓氏,则会返回“Mike Jones”,“Mike Johnson”和“Mike Jobs”。 我在此搜索中使用以下LINQ语句:

var users = (from u in context.TPM_USER where u.LASTNAME.ToLower().Contains(LastName.ToLower()) && u.FIRSTNAME.ToLower().Contains(FirstName.ToLower()) select u); 

(可能有或没有更好的方法来做一个不区分大小写的类似条款,但这似乎有效)

问题是如果用户输入名字或姓氏,但是将另一个字段留空。 如果我输入“Mike”作为名字并将“姓氏”字段留空,我想要返回所有Mikes而不管他们的姓氏。 除非两个字段至少填充了某些字段,否则上述查询不会返回任何结果。

我试过了:

 var users = (from u in context.TPM_USER where (LastName == "" || u.LASTNAME.ToLower().Contains(LastName.ToLower())) && (FirstName == "" || u.FIRSTNAME.ToLower().Contains(FirstName.ToLower())) select u); 

但是,除非两个字段都填写完毕,否则我仍然没有结果。 我在调试器下validation了LastName == ""确实是真的。

更新:

我做了一些调试,这实际上是一个Oracle问题。 生成的查询是:

 --Replaced the field list with * for brevity SELECT * FROM TPMDBO.TPM_USER "Extent1" WHERE (('jones' = '') OR ((INSTR(LOWER("Extent1".LASTNAME), LOWER('jones'))) > 0)) AND (('' = '') OR ((INSTR(LOWER("Extent1".FIRSTNAME), LOWER(''))) > 0)) 

乍一看似乎是正确的。 但是,Oracle似乎没有正确地短语短语('' = '') 。 事实上,如果我这样做:

 select * from TPM_USER where '' = '' 

我得零行。 我不是一个Oracle专家知道如何编写这个查询,但无论哪种方式都是一个entity framework方言错误。

只需有条件地添加谓词:

 var users = from u in context.TPM_USER select u; if (!string.IsNullOrWhiteSpace(FirstName)) users = users.Where(u => u.FIRSTNAME.ToLower().Contains(FirstName.ToLower())); if (!string.IsNullOrWhiteSpace(LastName)) users = users.Where(u => u.LASTNAME.ToLower().Contains(LastName.ToLower())); 

或者只将LASTNAME谓词作为条件谓词。

你确定FirstName和LastName不是null吗?

您可以尝试这样写它…

 string LowerFirstName = (FirstName + "").ToLower(); string LowerLastName = (LastName + "").ToLower(); var users = (from u in context.TPM_USER where (LowerLastName == "" || u.LASTNAME.ToLower().Contains(LowerLastName)) && (LowerFirstName == "" || u.FIRSTNAME.ToLower().Contains(LowerFirstName)) select u); 

仅供参考,如果有人遇到Oracle的这个问题,这是一个解决方法:

 var users = (from u in context.TPM_USER where (LastName == null|| u.LASTNAME.ToLower().Contains(LastName.ToLower())) && (FirstName == null || u.FIRSTNAME.ToLower().Contains(FirstName.ToLower())) select u); 

这将转换为:

 '' is null 

在SQL中,Oracle将其解释为true。

您只需在查询周围创建一个条件语句:

 if (String.IsNullOrWhiteSpace(LastName) && !String.IsNullOrWhiteSpace(FirstName)) { var users = (from u in context.TPM_USER where (u.FIRSTNAME.ToLower().Contains(FirstName.ToLower())) select u); } else if (String.IsNullOrWhiteSpace(FirstName) && !String.IsNullOrWhiteSpace(LastName)) { var users = (from u in context.TPM_USER where (u.LASTNAME.ToLower().Contains(LastName.ToLower())) select u); } 

您可以尝试检查搜索词的长度,看它是否在Oracle PL / SQL中有效。

 var users = (from u in context.TPM_USER where ((LastName ?? "").Trim().Length == 0 || u.LASTNAME.ToLower().Contains(LastName.ToLower())) && ((FirstName ?? "").Trim().Length == 0 || u.FIRSTNAME.ToLower().Contains(FirstName.ToLower())) select u);