2011-10-26 12 views
10

教育目的のために、私はLinqの実際の動作をVB.netのVB.netに変換しようとしました。LinqはVB.Netでグループ化しません

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」は、「Funny Stories」と「Bonjour mon Amour」の書籍は同じパブリッシャーおよび科目。 私の匿名キーは、2つの単純な文字列の新しいオブジェクトで構成されています。

私はすでにSOで検索しようとしましたが、otheror)の答えは私の問題を解決しません。 telerikcarlosagのような一部のコード翻訳者でさえ、この場合は助けになりません。

答えて

7

これが問題である:

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

残念ながらVBは、デフォルトでは匿名型で可変プロパティを使用し、変更可能なプロパティは、ハッシュの一部として考慮されていないので、C#バージョンと同等ではありませんコードまたは同等の操作。両方のプロパティを「キー」プロパティにする必要があります。

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は*すべてのプロパティをキープロパティとして扱います。これはバグのようなものです。これはLINQ to Objectsの「問題」ではありません。VBでの匿名型の仕組みの問題です。 –

5

サンプルを翻訳する努力を拍手していますが、C#とVBのLINQ in Actionのサンプルはすべてマニングサイト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 

あなたはラムダ構文を使用したい場合は@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