[英]Case-insensitive “contains” in Linq
我有一个 mvc 项目,我在其中使用了 linq。 在我的数据库中有一些记录,例如“某事”、“某事”、“某事”、“某事 ING”、“某事 ING”
我想做这个:
SELECT * FROM dbo.doc_dt_records WHERE name LIKE '%' + @records.Name + '%'
但是,如果我运行此代码,list.Count 返回 0。我该怎么办?
records.Name = "someth ing"; //for example
var rec = db.Records.ToList();
var lists = rec.Where(p => p.Name.Contains(records.Name)).ToList();
if (lists.Count > 0)
{
// do sthng
}
谢谢你的帮助...
最简单的方法是使用 ToLower() 方法
var lists = rec.Where(p => p.Name.ToLower().Contains(records.Name.ToLower())).ToList();
更好的解决方案(基于这篇文章: 不区分大小写的 'Contains(string)' )
var lists = rec.Where(p =>
CultureInfo.CurrentCulture.CompareInfo.IndexOf
(p.Name, records.Name, CompareOptions.IgnoreCase) >= 0).ToList();
这完全不是 LINQ 问题。
生成的 SQL 是否区分大小写取决于与表相关的排序规则。 在您的情况下,这可能不区分大小写。
你会从你发出的任何 SQL 中得到相同的结果。
使用IndexOf
和StringComparison.OrdinalIgnoreCase
:
p.Name.IndexOf(records.Name, StringComparison.OrdinalIgnoreCase) >= 0;
您可以创建这样的扩展函数:
public static bool Contains(this string src, string toCheck, StringComparison comp)
{
return src.IndexOf(toCheck, comp) >= 0;
}
据我了解,这个问题没有明确的答案。 问题是这样做的最佳方法取决于问题中未提供的细节。 例如,您使用什么准确的 ORM 以及您连接到什么准确的数据库服务器。 例如,如果您对 MS SQL Server 使用实体框架,则最好根本不要触及您的 LINQ 表达式。 您需要做的就是在与字符串进行比较的数据库/表/列上设置不区分大小写的排序规则。 这将比对 LINQ 表达式的任何更改都做得更好。 问题是,当 LINQ 转换为 SQL 时,最好将具有不区分大小写的排序规则的列与您的字符串进行直接比较,而不是其他任何东西。 只是因为它通常工作得更快,而且它是解决问题的自然方法。 您不希望最终查询类似于:
SELECT *
FROM AspNetUsers U
WHERE UPPER(U.Name) LIKE '%SOMETHING%';
想出类似的东西要好得多:
SELECT *
FROM AspNetUsers U
WHERE U.Name LIKE '%SOMETHING%';
但是 [Name] 列的排序规则不区分大小写。 不同之处在于,如果您假设索引包含 [Name] 列,则第二个查询可能会使用它,而第一个查询无论如何都会对表进行完整扫描。
因此,如果让我们说records
引用DBSet<T>
并且record
只是T
类型的一个对象。 你的代码是这样的:
var lists = records.Where(p => p.Name.Contains(record.Name)).ToList();
你在 SQL-server 上完成剩下的工作。 或者,如果您只需要知道列表中有任何值并且不需要这些值,那么这样做会更好:
if (records.Any(p => p.Name.Contains(record.Name)))
{
// do something
}
一般来说,如果你使用任何类型的 ORM 连接到任何类型的 SQL 服务器,你最好通过设置你的服务器/数据库/表/列的适当参数来做到不区分大小写。 只有在不可能或成本太高的情况下,您才会考虑其他可能性。 否则,您可能会遇到一些意想不到且非常不愉快的行为。 例如,Entity Framework Core 2.x 如果它不能将您的 LINQ 表达式直接转换为 SQL 查询,它正在做不同的技巧,用客户端操作替换服务器端操作。 因此,您最终可以得到一个解决方案,该解决方案将表中的所有数据提取到客户端并在那里对其进行过滤。 如果你的桌子足够大,这可能是一个很大的问题。
至于本地处理LINQ查询的情况,有很多方法可以做到。 我最喜欢的是下一个:
var lists = records.Where(p => p.Name
.Contains(record.Name, StringComparison.InvariantCultureIgnoreCase))
.ToList();
尝试这个
var lists = rec.Where(p => String.Equals(p.Name,records.Name,StringComparison.OrdinalIgnoreCase)).ToList();
请参阅此处获取文档
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.