LINQ-to-Objects - Что не так с этой простой группировкой составного ключа? - PullRequest
1 голос
/ 04 мая 2011

Хорошо, ребята ... впервые выложите вопрос здесь.Я пытаюсь продемонстрировать несколько функций LINQ и столкнулся с проблемой.Следующий запрос не выполняется должным образом:

Dim peopleByAgeAndName = _
    From p In (New PeopleRepository).GetAll
    Group By key = New With {p.Age, p.Name} Into Group
    Select Group

Вот очень простой PeopleRepository:

Public Class PeopleRepository
     Public Function GetAll() As List(Of Person)
        Dim people As New List(Of Person)
        people.Add(New Person With {.Name = "Test Name #1", .Age = 33})
        people.Add(New Person With {.Name = "Test Name #1", .Age = 33})
        people.Add(New Person With {.Name = "Test Name #2", .Age = 0})
        people.Add(New Person With {.Name = "Test Name #3", .Age = 0})
        people.Add(New Person With {.Name = "Test Name #4", .Age = 0})
        people.Add(New Person With {.Name = "Test Name #5", .Age = 35})
        people.Add(New Person With {.Name = "Test Name #1", .Age = 39})
        Return people
    End Function
End Class

А вот еще более простой класс Person:

Public Class Person
    Property Name As String
    Property Age As Integer
End Class

Очевидно, это все настройки кода для целей тестирования.После выполнения запроса peopleByAgeAndName я ожидаю получить 6 групп.Каждый из них содержит один объект Person, за исключением группы, соответствующей «Имя теста № 1» и возрастом 33 года. Но что бы я ни делал, я получаю 7 групп по одному элементу в каждой.

Есть мысли?Мне интересно, нормально ли это для LINQ-to-Objects?Опять же, это все тестирование кода.Я просто пытаюсь лучше понять, как это работает.Насколько я понимаю, при использовании анонимного объекта в качестве ключа он должен выполнять сравнение свойств по группам.Я ДОЛЖЕН получить 6 групп, а не 7.

Спасибо!

Обновление -

Для записи запрос, переписанный в C #, работает точно так, как я ожидаю:

 var peopleByAgeAndName =
        from p in peopleRepository.GetAll()
        group p by new {p.Age, p.Name}  into g 
        select g;

Я получаю 6 групп вместо 7. Я также подтвердил, что ключ группы недоступен в VB, но находится в C #.Странно как-то.

Ответы [ 3 ]

1 голос
/ 12 мая 2011

Я нашел решение для своей надуманной ситуации ... в Visual Basic необходимо добавить атрибут «Ключ» к любому свойству в анонимном типе, которое можно использовать для определения уникальности:

Dim peopleByAgeAndName = _
    From p In (New PeopleRepository).GetAll
    Group p By k = New With {Key p.Age, Key p.Name} Into g = Group
    Select g

Работает как шарм сейчас!Спасибо за ваш совет, ребята!

0 голосов
/ 04 мая 2011

Ключ группы - это то, по чему вы хотите группировать. Вы смешиваете группу и выбираете:

var grp=from p in persons
        group p by p.Name into g
        select new {g.Key, Ages=g};

Тогда вы бы повторили это так:

foreach(var name in grp)
{
  Console.WriteLine(name.Key);

  foreach(var age in name)
    Console.WriteLine("  "+age.Age);
}

Это очень упрощенно, но лучшая группировка будет выглядеть так:

var grp=from p in persons
        group p by p.Name into g
        select new {Name=g.Key, Ages=from a in g
                                     select a.Age};
0 голосов
/ 04 мая 2011

Вам нужен IEqualityComparer, который, возможно, предоставит вам различные объекты на основе идентификаторов.

...