2011-10-26 57 views
10

教育目的我想下面的LINQ表達式從書「中的LINQ行動」轉換成VB.netLINQ的不組在VB.Net

原來的C#

var list = 
    from book in SampleData.Books 
    group book by new { book.Publisher.Name, book.Subject } 
    into grouping 
    select new { 
    Publisher = grouping.Key.Publisher, 
    Subject = grouping.Key.Subject, 
    Book = grouping 
    }; 

我的嘗試:

Dim list = _books.GroupBy(Function(book) New With {.Publisher = book.Publisher.Name, 
                book.Subject}). 
        Select(Function(grouping) New With {.Publisher = grouping.Key.Publisher, 
                 .Subject = grouping.Key.Subject, 
                 .Books = grouping}) 

For Each item In list 
    Console.WriteLine("Publisher:" & item.Publisher & ", Subject:" & item.Subject) 
    For Each Book In item.Books 
    Console.WriteLine(" " & Book.Title) 
    Next 
Next 

這導致了以下的輸出:

Publisher:FunBooks, Subject:Fun 
    Funny Stories 
Publisher:Joe Publishing, Subject:Work 
    LINQ rules 
Publisher:Joe Publishing, Subject:Work 
    C# on rails 
Publisher:Joe Publishing, Subject:Fun 
    All your base are belong to us 
Publisher:FunBooks, Subject:Fun 
    Bonjour mon Amour 

我預料,書中的「LINQ規則」和「C#on rails」分組以及書籍「有趣的故事」和「Bonjour mon Amour」是因爲它們具有相同的發佈者和主題。 我的匿名鍵包含兩個簡單字符串的新對象。

我已經嘗試在SO中進行搜索,但是otheror)答案沒有解決我的問題。即使一些代碼翻譯器如telerikcarlosag在這種情況下也沒有幫助。

回答

7

這就是問題所在:

GroupBy(Function(book) New With {.Publisher = book.Publisher.Name, 
            book.Subject}) 

這並不等同於C#版本,因爲不幸的是VB默認使用的匿名類型可變屬性和可變屬性不被認爲是哈希的一部分代碼或平等操作。你需要使兩個屬性「鍵」屬性:

GroupBy(Function(book) New With {Key .Publisher = book.Publisher.Name, 
           Key book.Subject}) 

然後它應該工作正常。你可以閱讀更多關於VB on MSDN中的匿名類型。

+1

是這個偉大工程;非常感謝!哇,Jon Skeet自己的回答。我感到很榮幸。 :-) – Markus

+0

我測試了我的查詢,由於這在LINQPad中失敗了,我使用了LINQ to Entities源代碼。在我的代碼中,我實際上正在實現查詢(ToList)並從中運行組查詢,因爲我必須在此期間執行一些每行計算。這導致我相信這是LINQ to Objects而不是LINQ to Entities的一個問題。我假設這是因爲在LINQ to Entities中,分組表達式被轉換爲TSQL,而在LINQ to Objects中,散列碼被用於組鍵值相等。這聽起來正確嗎? – pseudocoder

+0

@pseudocoder:不,它不是關於哈希碼 - 它是關於哪些屬性用於確定相等性。這聽起來像是LINQ to Entities將* all *屬性當作關鍵屬性......這聽起來像是一個bug。這在LINQ to Objects中不是一個「問題」 - 這只是VB中匿名類型如何工作的問題。 –

5

雖然我讚賞你們翻譯樣本的努力,但實際上我們已經有了C#和VB中的LINQ in Action的所有樣本可供從Manning Site下載:http://www.manning.com/marguerie/。此外,我們已將樣品添加到LinqPad樣品中,以便輕鬆嘗試樣品並保存您的更改。請參閱http://www.thinqlinq.com/Default/LINQ-In-Action-Samples-available-in-LINQPad.aspx以獲取有關如何訪問該文件的說明。

看來您正在使用示例5.06b。稍微更新它,我們的VB翻譯是:

Dim query = _ 
    From book In SampleData.Books _ 
    Group book.Title By book.Publisher, book.Subject Into grouping = Group _ 
    Select _ 
    Publisher = Publisher.Name, _ 
    Subject = Subject.Name, _ 
    Titles = grouping 

如果你想使用的lambda語法,你需要指定Key作爲@johnskeet表示:

Dim list = SampleData.Books.GroupBy(Function(book) New With { 
          Key .Publisher = book.Publisher.Name, 
          Key .Subject = book.Subject}). 
       Select(Function(grouping) New With { 
        .Publisher = grouping.Key.Publisher, 
        .Subject = grouping.Key.Subject, 
        .Books = grouping}) 
+0

好吧,作者自己...... :-)感謝linq鏈接和代碼片段。 – Markus