为什么这个连接不工作

本文关键字:工作 连接 为什么 | 更新日期: 2023-09-27 18:04:34

在下面(从LinqPad粘贴)我的(非常愚蠢的)查询没有返回结果。为什么不呢,怎么了?(请把格式整理一下)

void Main()
{
    var csv =
@"#Books (format: ISBN, Title, Authors, Publisher, Date, Price)
0735621632,CLR via C#,Jeffrey Richter,Microsoft Press,02-22-2006,59.99
0321127420,Patterns Of Enterprise Application Architecture,Martin Fowler,Addison-Wesley, 11-05-2002,54.99
0321200683,Enterprise Integration Patterns,Gregor Hohpe,Addison-Wesley,10-10-2003,54.99
0321125215,Domain-Driven Design,Eric Evans,Addison-Wesley Professional,08-22-2003,54.99
1932394613,Ajax In Action,Dave Crane;Eric Pascarello;Darren James,Manning Publications,10-01-2005,44.95";
  using (var reader = new StringReader(csv) /*new StreamReader("books.csv")*/)
  {
    var books =
      from line in reader.Lines()
      where !line.StartsWith("#")
      let parts = line.Split(',')
      select new { Isbn=parts[0], Title=parts[1], Publisher=parts[3] };
    //books.Dump();
    var query =
    from book in books
    from b in books
    where book.Isbn == b.Isbn
    select new 
    {       
        book.Isbn,
        book.Title
    };
    query.Dump();

    // Warning, the reader should not be disposed while we are likely to enumerate the query!
    // Don't forget that deferred execution happens here
  }
}
}// Temporary hack to enable extension methods
/// <summary>
/// Operators for LINQ to Text Files
/// </summary>
public static class Extensions
{
  public static IEnumerable<String> Lines(this TextReader source)
  {
    String line;
    if (source == null)
      throw new ArgumentNullException("source");
    while ((line = source.ReadLine()) != null)
      yield return line;
  }

为什么这个连接不工作

在第二个查询中尝试枚举两次books集合。但是,这不能按原样工作,因为您的Lines()扩展方法首先要通过读取器读取到末尾。由于延迟执行,第二个枚举尝试从现在为空的读取器中读取,导致没有结果。

您需要将books集合的结果放入列表(或其他集合)中,因此它不会再次尝试访问阅读器。在你的情况下,你可以在你的藏书上调用ToList(),它应该从那里工作。

var books =
   (from line in reader.Lines()
    where !line.StartsWith("#")
    let parts = line.Split(',')
    select new { Isbn = parts[0], Title = parts[1], Publisher = parts[3] })
   .ToList();

. tolist()应该完成这项工作。如此:

void Main()
{
    var csv =
@"#Books (format: ISBN, Title, Authors, Publisher, Date, Price)
0735621632,CLR via C#,Jeffrey Richter,Microsoft Press,02-22-2006,59.99
0321127420,Patterns Of Enterprise Application Architecture,Martin Fowler,Addison-Wesley, 11-05-2002,54.99
0321200683,Enterprise Integration Patterns,Gregor Hohpe,Addison-Wesley,10-10-2003,54.99
0321125215,Domain-Driven Design,Eric Evans,Addison-Wesley Professional,08-22-2003,54.99
1932394613,Ajax In Action,Dave Crane;Eric Pascarello;Darren James,Manning Publications,10-01-2005,44.95";
  using (var reader = new StringReader(csv) /*new StreamReader("books.csv")*/)
  {
    var books =
      (from line in reader.Lines()
      where !line.StartsWith("#")
      let parts = line.Split(',')
      select new { Isbn=parts[0], Title=parts[1], Publisher=parts[3] }).ToList();
    //books.Dump();
    var query =
    from book in books
    from b in books
    where book.Isbn == b.Isbn
    select new 
    {       
        book.Isbn,
        book.Title
    };
    query.Dump();

    // Warning, the reader should not be disposed while we are likely to enumerate the query!
    // Don't forget that deferred execution happens here
  }
}
}// Temporary hack to enable extension methods
/// <summary>
/// Operators for LINQ to Text Files
/// </summary>
public static class Extensions
{
  public static IEnumerable<String> Lines(this TextReader source)
  {
    String line;
    if (source == null)
      throw new ArgumentNullException("source");
    while ((line = source.ReadLine()) != null)
      yield return line;
  }

"Lines"方法意味着您的源代码是由1+个字符串组成的,这些字符串由新行结束。我不认为上面的c#代码会像你期望的那样识别终止