为什么这个linq加入不起作用?

时间:2011-08-03 08:18:32

标签: c# linq

在下面(从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;
  }

3 个答案:

答案 0 :(得分:4)

您尝试在第二个查询中两次枚举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();

答案 1 :(得分:2)

.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;
  }

答案 2 :(得分:0)

“Lines”方法意味着您的源由1 +串由新行终止分隔。我不认为上面的C#代码会像你期望的那样识别终止。