【问题标题】:C# check string contain a word with underscoresC# 检查字符串是否包含带下划线的单词
【发布时间】:2018-09-19 22:03:25
【问题描述】:

我想获取所有包含“_AT_”或“PV_”的项目, 但是d.Nom.Contains($"PV_")d.Nom.Contains($"_AT_") 也获取仅包含“AT”和“PV”的项目

 IQueryable<DocumentMetadata> docPV = NHibernateSession.Current.Query<DocumentMetadata>()
           .Where(d => d.IdEntiteRattachement == missionId
                       && d.Nom.Contains($"PV_")
                       && d.Desactive == false)
           .OrderByDescending(d => d.DateDerniereModif);

        IList<DocumentMetadata> docAR = NHibernateSession.Current.Query<DocumentMetadata>()
           .Where(d => d.IdEntiteRattachement == missionId
                       && d.Nom.Contains($"_AT_")
                       && d.Desactive == false)
           .OrderByDescending(d => d.DateDerniereModif).ToList();

【问题讨论】:

  • &amp;&amp; (d.Nom.Contains($"PV_") || d.Nom.Contains($"_AT_"))?
  • 您是在问如何结合这些条件?如&amp;&amp; (d.Nom.Contains($"PV_") || d.Nom.Contains($"_AT_"))
  • 在 SQL 中,下划线(和百分比)是通配符。你必须逃离他们。您很可能会在文档中找到它。
  • 是不是因为下划线充当了通配符?这有帮助吗 - stackoverflow.com/questions/5821/…? (即 d.Nom.Contains(@"PV_") - 注意你需要 '@' 因为 \ 本身就是一个转义字符。
  • 不要因为不清楚而关闭这个问题。恕我直言,这是一个明确的问题:过滤Contains("_AT_") 也会找到仅包含"AT" 的字符串。 (但它可能是重复的。)

标签: c# string nhibernate contains linq-to-nhibernate


【解决方案1】:

在 SQL 中,下划线(和百分比)是通配符。 NHibernate 不会自动转义它们,因为您可以使用它们。在.Contains后面,是SQL的LIKE

转义通配符取决于底层 DBMS。

试试这个:

d.Nom.Contains("\\_AT\\_")

(它可能不起作用。请参阅数据库引擎的文档。)

【讨论】:

  • .Contains(@"\_AT\_")
  • 我测试了这两个代码,但它们不起作用。然后我使用Nom.Replace("_","|").Contains("PV|")
  • 听起来像是一个可行的解决方案。但是,它有两个缺点:您无法区分“PV_”和“PV|”,并且数据库不会使用索引。当数据库运行LIKE 时,它通常无论如何都不能使用索引。但可能会有特殊的优化,例如当使用StartsWith 而不是Contains 时。这取决于数据库。你用什么数据库?
  • 对于许多常见的数据库,它通常可以为 LIKE 使用索引(对于某些工作),假设模式包含非通配符初始部分。
  • @OskarBerggren:是的,这就是为什么我说StartsWith 而不是Contains
【解决方案2】:

不知何故,上面给出的解决方案都不能正确转义下划线(我试过\\_ @\_ [_] $_ ^_)所以我最终在纯LINQ中再次过滤:

var list = dc.Employees.Where(a => a.Name.Contains(partial)).ToList();
if (partial.Contains("_")) // underscore is an sql wildcard character and will match anything, so filter again in .NET linq
    list = list.Where(a => a.Name.Contains(partial)).ToList();

这显然不是最好的解决方案,因为它从数据库中检索的行数超过了必要的数量,并在内存中再次过滤,但在我的情况下,开销是可以接受的。

【讨论】:

    猜你喜欢
    • 2014-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-23
    • 1970-01-01
    • 1970-01-01
    • 2020-06-21
    相关资源
    最近更新 更多