Linq не группируется в VB.Net
В образовательных целях я попытался преобразовать следующее выражение Linq из книги "Linq in action" в VB.net
Оригинал С#
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" и "С# на рельсах" сгруппированы, а также книги "Забавные истории" и "Bonjour mon Amour", потому что они имеют один и тот же Publisher и Subject.
Мой анонимный ключ состоит из нового объекта из двух простых строк.
Я уже пытался искать в SO, но другие (или) ответы не решают мою проблему, Даже некоторые переводчики кода, такие как telerik или carlosag не помогают в этом случае.
Ответы
Ответ 1
В этом проблема:
GroupBy(Function(book) New With {.Publisher = book.Publisher.Name,
book.Subject})
Это не эквивалентно версии С#, поскольку, к сожалению, VB по умолчанию использует изменчивые свойства в анонимных типах, а изменчивые свойства не рассматриваются как часть хеш-кода или операций равенства. Вам необходимо создать оба свойства свойств "Ключ":
GroupBy(Function(book) New With {Key .Publisher = book.Publisher.Name,
Key book.Subject})
Тогда он должен работать нормально. Вы можете больше узнать об анонимных типах в VB в MSDN.
Ответ 2
Пока я приветствую ваши усилия по переводу образцов, на самом деле у нас есть все образцы для LINQ in Action в С# и VB, доступные для загрузки с сайта Manning: 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})