For educational purposes I tried to convert the following Linq expression from the book "Linq in action" into VB.net
Original 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
};
My attempt:
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
This leads to the following output:
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
I expected, that the books "LINQ rules" and "C# on rails" are grouped as well as the books "Funny Stories" and "Bonjour mon Amour" because they have the same Publisher and Subject. My anonymous key consists a new object of two simple strings.
I already tried to search in SO, but other (or) answers do not solve my problem. Even some code translators like telerik or carlosag are no help in this case.
This is the problem:
GroupBy(Function(book) New With {.Publisher = book.Publisher.Name,
book.Subject})
That's not equivalent to the C# version, because unfortunately VB uses mutable properties in anonymous types by default, and mutable properties aren't considered as part of the hash code or equality operations. You need to make both properties "Key" properties:
GroupBy(Function(book) New With {Key .Publisher = book.Publisher.Name,
Key book.Subject})
Then it should work fine. You can read more about anonymous types in VB on MSDN.
While I applaud your efforts to translate the samples, we actually have all of the samples for LINQ in Action in C# and VB available for download from the Manning Site: http://www.manning.com/marguerie/. Also, we have added samples to the LinqPad samples to make it easy to try the samples and save your changes. See http://www.thinqlinq.com/Default/LINQ-In-Action-Samples-available-in-LINQPad.aspx for instructions on how to access that.
It appears that you are working on example 5.06b. Updating it slightly, our VB translation is:
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
If you want to use the Lambda syntax, you do need to specify the Key as @johnskeet indicated:
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})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With