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

标签 c# .net linq oracle 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);

(可能有也可能没有更好的方法来制作不区分大小写的 like 子句,但这似乎有效)

问题在于,如果用户输入名字或姓氏,但随后将其他字段留空。如果我输入“Mike”作为名字并将姓氏字段留空,我想返回所有 Mike,而不考虑他们的姓氏。上述查询不会返回任何结果,除非两个字段都至少填充了一些内容。

我试过:

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);

但是,除非填写两个字段,否则我仍然得不到任何结果。我已经在调试器下验证了 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 谓词作为条件谓词。

后来补充:

最好避免像 Where(u => u.FIRSTNAME.ToLower()... 这样的表达式。它们会导致 FIRSTNAME 上的任何索引被忽略, 因为先转换字段值然后再比较(更多详细信息请参见 here)。

您很有可能不需要这些小写转换。检查字段的数据库排序规则。如果它不区分大小写 (CI)(可能是这样),则您不需要这些转换。

关于c# - 使用 Entity Framework 在数据库中搜索文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10936176/

相关文章:

c# - 如何释放为 Excel 创建的对象 (C#)

.net - 网络安全-MVC

c# - DataGridView 加载速度非常慢。如何优化 DataGridView 中的行添加?

c# - 公开 LINQ 查询的 protected 集合

linq - C# Linq 在多列上连接 2 个表并使用 GROUP BY 进行计数

c# - 使用linq合并表类数据结构的有效方法

c# - 重用 LINQ 查询

c# - 从文件中获取原始文件名

c# - 如何在 C# 中返回隐式缩小和扩大的 UInt?

.net - 在没有 NodeJs 和 JSPM 的情况下运行 Aurelia 框架