【问题标题】:(C#) LINQ — Cannot find any result with method .Contains()(C#) LINQ — 使用方法 .Contains() 找不到任何结果
【发布时间】:2020-03-15 15:56:44
【问题描述】:

我有两个查询要按名称搜索 Authors 和按标题搜索 Books。第一个按预期工作,正在查看是否有任何作者的姓名包含我的输入。出于某种原因,我不能对书名做同样的事情。当我知道 它是 string...

时,我收到一条错误消息,提示我无法对 char 采取行动

它们之间的唯一区别是我使用的是List<string> Namesstring Title


按“作者姓名”查询(工作)

author = from book in Serialisation.Books
         where book.Author.Names.Any(author => author.Contains(InputBook.Text))
         select book;

当我将鼠标悬停在author => author 上时,它告诉我这是一个字符串参数。属性 Names 是 List<string> Names,因为某些书籍可能有 2 个作者。我能够找到任何与只有一个字母的搜索相对应的作者姓名。

例如:« M » 输出 => Margaret Atwood


按“书名”查询(无效)

book = from book in Serialisation.Books
       where book.Title.Any(x => x.Contains(InputBook.Text))
       select book;

在这里,当我将鼠标悬停在 x => x 上时,它告诉我这是一个 char 参数,因此我不能使用方法 .Contains()...

我得到的唯一解决方案是改写这个:

book = from book in Serialisation.Books
       where book.Title == InputBook.Text
       select book;

这当然不是我想要的。我不知道要改变什么才能让它工作..

编辑: 我试过book.Title.Contains(InputBook.Text),后来我收到一个错误,告诉我在转换输出时我不能得到空值。ToList()


课本

public class Book 
{
    public string Title { get; set; }
    public Author Author { get; set; }
    // my other class Author is simply a list of names. 
    // I need it to override the method ToString() so that 
    // when there is two authors for the same book, I only have 
    // one string to look into for my query.
}

【问题讨论】:

  • 为什么不使用book.Title.Contains(InputBook.Text)?我是否误解了您的要求?
  • 不,你没有。我已经尝试过了,但是无论我在输入中尝试什么,我都会收到 NullException。
  • 我认为您需要为此忽略文化案例。看看@tymtam 的答案

标签: c# linq webforms


【解决方案1】:
where book.Title.Any(x => x.Contains(searchTerm))

无法编译,因为您将 Title 解构为字符集合。它说:给我所有的书名,每个字符都包含我的搜索词。

我想你想要

where book.Title.Contains(searchTerm))

这说:给我所有标题包含搜索词的书。

从您的 cmets 看来,有些书的标题为空。在这种情况下我们需要提防这种情况,否则Title.Contains 将抛出NullReferenceException

where !string.IsNullOrEmpty(book.Title) &&
               book.Title.Contains(searchTerm)

这表示:给我所有标题不为空且不为空且包含 searchTerm 的书。

最后,您可能希望确保搜索不区分大小写。

where !string.IsNullOrEmpty(book.Title) &&
               book.Title.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase)

测试

string searchTerm = "Adventures";
var books = new [] { 
    new Book{Title = "Adventures in Code"},
    new Book{Title = "My adventures in Oz"},
    new Book{Title = "About Linq"},
    new Book{Title = null} // no title
    };
var found = from book in books
        where !string.IsNullOrEmpty(book.Title) &&
               book.Title.Contains(searchTerm, StringComparison.InvariantCultureIgnoreCase)
        select book;
foreach( var b in found ) Console.WriteLine(b.Title);

输出

Adventures in Code
My adventures in Oz

【讨论】:

  • 我也试过了,因为我没有收到任何错误。经测试,我得到一个 nullException,因为该值不能为空。我只用几个字母和完整的标题进行了测试。两者都是空的。
  • 添加了 null 处理。没有标题的书不是我所期望的,tbh。
  • 我不确定我是否理解该属性上的 IsNullOrEmpty。但现在它似乎起作用了。
【解决方案2】:

您的属性Titlestring,在大多数语言中,包括C#string 实际上是char 的数组

linq 查询 Any 正在对数组进行迭代,所以由于属性是 string,它本身就是 char[],我检查 Anychar 是否与谓词匹配。

您正在寻找的是比较字符串本身是否包含另一个字符串。因此你需要使用:

where book.Title.Contains(InputBook.Text)

【讨论】:

    猜你喜欢
    • 2020-11-22
    • 2010-09-16
    • 2017-10-07
    • 2021-04-03
    • 1970-01-01
    • 1970-01-01
    • 2012-11-10
    • 1970-01-01
    • 2011-08-07
    相关资源
    最近更新 更多