开发者

LINQ-to-Objects - What's wrong with this simple Composite Key grouping?

Ok guys... first time posting a question on here. I'm trying to demo a couple features of LINQ and have hit a snag. The following query isn't performing as expected:

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

Here is the very simple 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

And here is the even simpler Person class:

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

Obviously this is all code setup for testing purposes. After executing the peopleByAgeAndName query, I expect to get 6 grou开发者_如何学编程ps. Each containing one Person object except the group corresponding to "Test Name #1" and an age of 33. No matter what I do, though, I get 7 groups of one element each.

Any thoughts? I'm wondering if this is normal for LINQ-to-Objects? Again, it's all testing code. I'm just trying to better understand how this works. It was my understanding that when using an anonymous object as the key, it should do a property-by-property comparison for the groups. I SHOULD be getting 6 groups, not 7.

Thanks!

Update -

For the record, the query rewritten in C# performs exactly as I expect:

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

I get 6 groups instead of 7. I also confirmed that the group key is not available in VB but is in C#. Kinda weird.


I found the solution for my contrived situation... in Visual Basic, you have to add the "Key" attribute to any property in an Anonymous Type that can be used to determine uniqueness:

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

Works like a charm now! Thanks for your advice guys!


You need an IEqualityComparer that'll give you distinct objects based on Ids perhaps.


The group key is what you want to group by. You're mixing up group and select:

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

Then you'd iterate over it like this:

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

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

This is very simplistic though, a better grouping would be like:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜