1

I am having a hard time grouping a dbset (EntityFramework) by two fields and sending that output to a strongly typed view.

When I use an anonymous type for the composite key I get the right output. A list containing one item and that item in turn has two or more grouping items.

Now if I use a class instead I get a list of two items and in turn each item has one grouping item.

var output = context.Transfers.GroupBy(t=> new { t.TNumber, t.Type}).ToList();

var output2 = context.Transfers.AsEnumerable()
                     .GroupBy(t => new OTSpecs(t.TNumber, t.Type)).ToList();

OTSpecs is just a simple class, with those public fields and a parameter constructor.

I need to add the AsEnumerable() otherwise I get a System.NotSupportedException Only parameterless constructors and initializers are supported in LINQ to Entities

Also because I need to define the model in the view like this

@model IEnumerable<IGrouping<OTSpecs, Transfer>>

unless of course it is possible to replace OTSpecs in that line with the anonymous type. But I don't know how.

My question is why those lines of code produce a different output? Is it possible to define the model in the view replacing the OTSpecs for a anonymous type?

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
  • context.Transfers is a DataTable. To enumerate through the rows, you need to add "AsEnumerable(). When you have a class you need a List() object for the class like : List specs = new List(); Then you should be able to use : specs.Group(t => new { t.TNumber, t.Type}).ToList(); – jdweng Feb 04 '19 at 15:50

1 Answers1

3

Anonymous types implement equality comparison which compares all their properties. So when you are using anonymous type as a key, linq is able to identify that two key objects are same and should be grouped together.

Your custom object, I suspect, does not implement that stuff, so for it just general object comparison is used, which just compares references. Two key objects have difference references - thus different groups.

To fix this, you may need to either pass in equality comparer, or implement Equals in your class OTSpecs.

Andrei
  • 55,890
  • 9
  • 87
  • 108
  • Thanks @RobertHarvey for making me post a better question and Andrei for the answer. I was not fully aware of that. I implemented Equals and GetHashCode and it is working how I expected. – Edward Sanxs Feb 04 '19 at 16:03