linq 不区分大小写(没有 toUpper 或 toLower)

Posted

技术标签:

【中文标题】linq 不区分大小写(没有 toUpper 或 toLower)【英文标题】:linq case insensitive (without toUpper or toLower) 【发布时间】:2011-07-15 19:36:31 【问题描述】:
public Articles GetByName(string name, Categories category, Companies company)

    var query = from article in session.Linq<Articles>()
                where article.Name == name &&
                      article.Category == category &&
                      article.Company == company
                select article;
    return query.FirstOrDefault();

查询如何不区分大小写。我可以使用 toLower 或 toUpper 但我想使用 OrdinalIgnoreCase。有可能吗?

【问题讨论】:

LINQ Contains Case Insensitive的可能重复 【参考方案1】:

使用String.Equals 和适当的参数使其不区分大小写

mySource.Where(s => String.Equals(s, "Foo", StringComparison.CurrentCultureIgnoreCase));

【讨论】:

嗯,现在我得到值不能为空。参数名称:left 你确定吗? String.Equals 应该能够接受 null 作为参数。 如果我使用 toUpper 那么我得到索引超出范围。必须是非负数且小于集合的大小。参数名称:索引。仅适用于我粘贴的代码... FirstOrDefault 可能返回 null,您可能会在未先检查的情况下使用它。稍微分解一下你的代码并确定 String.Equals 是什么失败了,因为 String.Equals 应该能够接受 null 作为参数 可能。 NH 的 Linq 解析器可能会被 String.Equals 混淆?可以肯定的是,您使用的是 String.Equals(s1, s2) 而不是 str.Equals(str2),对吧?【参考方案2】:

使用.Equals(name, StringComparison.OrdinalIgnoreCase) 方法代替==

var query = from article in session.Linq<Articles>()
            where article.Name.Equals(name, StringComparison.OrdinalIgnoreCase) &&
                  article.Category.Equals(category) &&
                  article.Company.Equals(company)
            select article;

return query.FirstOrDefault();

【讨论】:

请注意 String.Equals() 和 StringComparison 与 LINQ 的结合。根据数据库系统,该选项可以被忽略。例如。 SQLite 或 Oracle。【参考方案3】:

如果这是针对具有不区分大小写排序规则的数据库的 LINQ to SQL 查询,则它已经不区分大小写。请记住,LINQ to SQL 实际上并没有执行您的 == 调用;它将其视为表达式并将其转换为 SQL 中的相等运算符。

如果它是 LINQ to Objects,那么您可以使用 String.Equals,正如其他海报所指出的那样。

【讨论】:

【参考方案4】:
var query = from article in session.Linq<Articles>()
           where string.Equals(article.Name,name, StringComparison.OrdinalIgnoreCase) &&
                 string.Equals(article.Category,category, StringComparison.OrdinalIgnoreCase) &&
                 string.Equals(article.Company,company, StringComparison.OrdinalIgnoreCase)
                        select article;

            return query.FirstOrDefault();

Name,Category,Company 为null时也会处理

【讨论】:

不一定支持此特定解决方案。例如使用 Linq2SQL,在 SQLServer2008 上:Method 'Boolean Equals(System.String, System.String, System.StringComparison)' has no supported translation to SQL. 同样:'Boolean Equals(System.String, System.StringComparison)' has no supported translation to SQL. @mcdrewski 我实际上得到了Incorrect number of arguments supplied for call to method 'Boolean Equals(System.String, System.String, System.StringComparison)',即使我清楚地提供了预期的参数。我认为使用 EF4 可能是一个错误。 @drzaus 使用属性中的 Equals 方法而不是类型中的静态方法来使用 Edgar 的答案。【参考方案5】:

使用

String.Equals(article.Name, name, StringComparison.OrdinalIgnoreCase)

【讨论】:

呵呵 - 以前从未使用过OrdinalIgnoreCase - 那和CurrentCultureIgnoreCase 有什么区别? @Adam Racks: RTFM ;) 基本上,您的解决方案考虑了当前文化的比较规则,而我的解决方案在将两个字符串都设为大写后进行了简单的逐字节比较。谷歌或 SO 搜索将提供有关该主题的大量信息。【参考方案6】:

如果您使用的是 C# 6.0,您可以定义一个简短的扩展方法,以便在构建 LINQ 语句时使用:

public static bool EqualsInsensitive(this string str, string value) => string.Equals(str, value, StringComparison.CurrentCultureIgnoreCase);

用法:

query.Where(item => item.StringProperty.EqualsInsensitive(someStringValue));

对于低于 6.0 的 C#,它将如下所示:

public static bool EqualsInsensitive(this string str, string value) 

    return string.Equals(str, value, StringComparison.CurrentCultureIgnoreCase);

【讨论】:

【参考方案7】:

改成

public Articles GetByName(string name, Categories category, Companies company)
        
    var query = from article in session.Linq<Articles>()
                            where string.Equals(article.Name, StringComparison.CurrentCultureIgnoreCase)  == name &&
                                string.Equals(article.Category, StringComparison.CurrentCultureIgnoreCase == category &&
                                string.Equals(article.Company, StringComparison.CurrentCultureIgnoreCase == company
                            select article;

                return query.FirstOrDefault();

【讨论】:

【参考方案8】:

您确定您的数据库支持时使用 string.Equals(name, article.Name, StringComparison.OrdinalIgnoreCase)。

例如带有 NOCASE 排序规则的 SQLite 将忽略该选项。 Oracle 使用将采用的会话设置 NLS_COMP、NLS_SORT。

如果您没有文化问题,请使用 ToLower() 或 ToUpper()。

【讨论】:

以上是关于linq 不区分大小写(没有 toUpper 或 toLower)的主要内容,如果未能解决你的问题,请参考以下文章

LINQ to DataSet 不区分大小写分组方式

LINQ to Entities 区分大小写比较

c# 中的 LastIndexOf()函数能不区分大小写吗

忽略重音和大小写的 LINQ

在带有 LINQ to XML 的 VB.NET 中,where 子句在属性值和字符串之间设置不区分大小写的比较

多列不区分大小写的组