2011-08-03 58 views
0

在下面(從LinqPad粘貼)我的(非常愚蠢)查詢返回沒有結果。爲什麼不,什麼是錯的? (請別人排序格式)爲什麼這個linq連接不起作用?

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; 
    } 
+2

你試過'Lines()。ToList'。 –

回答

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(); 
+0

這比Saeed的評論更好,因爲它阻止了整個解析(與分裂相反)執行兩次。 –

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

「行」方法意味着您的源由1+個字符串構建,並由一個換行符終止。我不認爲上面的C#代碼會按照您的預期來識別終止。