C# 不区分大小写“;包括「;林克

C# 不区分大小写“;包括「;林克,c#,linq,C#,Linq,我有一个mvc项目,我在其中使用linq。 在我的数据库中有一些记录,例如“Someth ing”、“Someth ing”、“Someth ing”、“Someth ing” 我想这样做: SELECT * FROM dbo.doc_dt_records WHERE name LIKE '%' + @records.Name + '%' 但是,如果我运行此代码,list.Count将返回0。我该怎么办 records.Name = "someth ing"; //for exampl

我有一个mvc项目,我在其中使用linq。 在我的数据库中有一些记录,例如“Someth ing”、“Someth ing”、“Someth ing”、“Someth 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()方法

更好的解决方案(基于此帖子:)


使用
IndexOf
StringComparison.ordinallingorecase

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;
}
var lists = records.Where(p => p.Name.Contains(record.Name)).ToList();
if (records.Any(p => p.Name.Contains(record.Name)))
{
    // do something
}

这完全不是LINQ的问题

生成的SQL的大小写敏感度取决于与表相关的排序规则。在您的情况下,它可能不区分大小写

从发出的任何SQL都会得到相同的结果。

试试这个

var lists = rec.Where(p => String.Equals(p.Name,records.Name,StringComparison.OrdinalIgnoreCase)).ToList();

参考文档

据我所知,这个问题没有明确的答案。问题是这样做的最佳方式取决于问题中没有提供的细节。例如,您使用什么样的ORM,连接到什么样的DB服务器。例如,如果您对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%';
最好能想出这样的办法:

SELECT  *
  FROM  AspNetUsers     U
 WHERE  UPPER(U.Name)   LIKE '%SOMETHING%';
SELECT  *
  FROM  AspNetUsers U
 WHERE  U.Name      LIKE '%SOMETHING%';
但是使用[Name]列的不区分大小写的排序规则。区别在于,如果您有包含[Name]列的索引,第二个查询可能会使用它,第一个查询无论如何都会对表进行完整扫描

因此,如果说
records
引用了
DBSet
,那么
record
只是
T
类型的一个对象。您的代码如下所示:

public static bool Contains(this string src, string toCheck, StringComparison comp)
{
    return src.IndexOf(toCheck, comp) >= 0;
}
var lists = records.Where(p => p.Name.Contains(record.Name)).ToList();
if (records.Any(p => p.Name.Contains(record.Name)))
{
    // do something
}
其余的都在SQL server上完成。或者,如果您只需要知道列表中有任何值,而不需要这些值,则最好这样做:

public static bool Contains(this string src, string toCheck, StringComparison comp)
{
    return src.IndexOf(toCheck, comp) >= 0;
}
var lists = records.Where(p => p.Name.Contains(record.Name)).ToList();
if (records.Any(p => p.Name.Contains(record.Name)))
{
    // do something
}
一般来说,如果使用连接到任何类型SQL server的任何类型的ORM,最好通过设置服务器/数据库/表/列的适当参数来实现大小写不敏感。只有不可能或太贵的时候,你考虑其他的可能性。否则,你可能会突然做出一些意想不到的、非常不愉快的行为。例如,EntityFrameworkCore2.x如果不能将LINQ表达式直接转换为SQL查询,那么它正在使用不同的技巧,用客户端操作替换服务器端操作。因此,您可以最终得到一个解决方案,该解决方案将表中的所有数据提取到客户机并在那里进行过滤。如果你的桌子够大,可能会有很大的问题

至于LINQ查询在本地处理的情况,有很多方法可以做到这一点。我最喜欢的是下一个:

        var lists = records.Where(p => p.Name
            .Contains(record.Name, StringComparison.InvariantCultureIgnoreCase))
            .ToList();

重新打开,因为LINQ中的副本指向内存中的解决方案,忽略了核心问题-这是错误排序规则中的SQL“问题”。contains函数还有第二个重载,您可以在其中设置IEqualityComparer,对于字符串和ignorcase,它是:items.contains(“teszt”,StringComparer.CurrentCultureIgnorCase)LINQ to Entities无法识别方法“Int32 IndexOf(System.String,System.String,System.Globalization.CompareOptions)”方法,并且无法将此方法转换为存储表达式。