Ehsan Akbar
Ehsan Akbar

Reputation: 7299

groupby doesn't work in linq ,result are same like input

I have an structure like this :

 public  class DebtCreditorRPT
    {
        [DisplayName("شناسه مشتری")]
        public string Memberid { get; set; }
        [DisplayName("نام ")]
        public string Name { get; set; }
        [DisplayName("مبلغ")]
        public string Amount { get; set; }
}

And values like these:

id      companyname       amount
1         a                12
2         b                13
1         a                14

And query like this using groupby:

  List<DebtCreditorRPT> result=new List<DebtCreditorRPT>();

enter image description here

The result that i need should be like this :

      companyname       amount
        a                26
        b                13

But it doesn't work .the result that i get from the above query is like input :

id      companyname       amount
1         a                12
2         b                13
1         a                14

why ?

Here is the real result that i get :

enter image description here best regards

Upvotes: 0

Views: 782

Answers (4)

Michael Sandler
Michael Sandler

Reputation: 1309

I had the same problem while working in VB.Net, not C#, and found that unlike C#, VB.Net compares anonymous types by reference, not by the component values. To avoid this, you have to explicitly designate particular fields as keys using the Key keyword:

result.GroupBy(i => New With {Key i.Memberid, Key i.Name}).Select(g => new
{ 
    Name = g.Key.Name,
    Amount = g.Sum(x => double.Parse(x.Amount))
}).ToList();

I see that you are working in C#, so I'm not sure why the suggested answers do not work for you. Linq seems to be using the memory address of the item for comparison (which will be different for every item even if the fields are exactly the same), not the individual elements.

To group in the manner you want you could use a string concatenated from the values of the key elements. This works because strings are compared by their contents, not by their addresses in memory:

result.GroupBy(i => i.Memberid.ToString() + i.Name).Select(g => new
{ 
    Name = g.FirstOrDefault().Name,
    Amount = g.Sum(x => double.Parse(x.Amount))
}).ToList();

Upvotes: 0

M&#229;ns Vestin
M&#229;ns Vestin

Reputation: 1

It looks as if you assume that GroupBy changes the input collection which it is applied to. This is not the case, it returns a new collection. (In your example, the grouped collection is not even of the same type as the input collection.)

Try this:

List<DebtCreditorRPT> groupedList = nonGroupedList.GroupBy(i => new 
  { 
    i.Memberid, 
    i.Name
  }).Select(g => new DebtCreditorRPT 
  {
    Name = g.Key.Name,
    Amount = g.Sum(x => double.Parse(x.Amount)).ToString(), 
    Memberid = g.Key.Memberid
  }).ToList();

Upvotes: 0

Dennis_E
Dennis_E

Reputation: 8904

Looks like you need to group by id and name

result.GroupBy(i => new {i.Memberid, i.Name}).Select(g => new
          { 
              Name = g.Key.Name,
              Amount = g.Sum(x => double.Parse(x.Amount))
          }).ToList();

Upvotes: 1

NeddySpaghetti
NeddySpaghetti

Reputation: 13495

Try changing your query to:

  List<DebtCreditorRPT> result=new List<DebtCreditorRPT>();
  result.GroupBy(i=>i.Name).Select(g => new
              { 
                  Name = g.Key,
                  Amount = g.Sum(x => double.Parse(x.Amount))
              }).ToList();

Upvotes: 1

Related Questions