Solved

LINQ: group by from datatable

Posted on 2012-03-30
7
4,315 Views
Last Modified: 2012-06-27
Hi,

I read a DBF file (with more than 1.000.000 records) into a datatable.
I can read that data, but now I want to group by on 2 columns (sampnumber,testcode)

Once I know the unique records by (sampnumber,testcode), I want the last 29 records for  every sampnumber,testcode in the data.

I've been looking for the solution, but I just can't find it.

The columns I have:
sampnumber, sampname, samplenr, date, testcode, testname, result, unit

Thanks.
0
Comment
Question by:VampValdo
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
7 Comments
 
LVL 20

Expert Comment

by:BuggyCoder
ID: 37785951
Here is sample code:-
var dt = new DataTable();
            dt.Columns.Add("Number", typeof (int));
            dt.Columns.Add("Code", typeof(int));
            dt.Columns.Add("Unit", typeof(int));

            var dr = dt.NewRow();
            dr.SetField<int>("Number", 1);
            dr.SetField<int>("Code", 12);
            dr.SetField<int>("Unit", 3);

            dt.Rows.Add(dr);

            dr = dt.NewRow();
            dr.SetField<int>("Number", 1);
            dr.SetField<int>("Code", 13);
            dr.SetField<int>("Unit", 34);

            dt.Rows.Add(dr);

            dr = dt.NewRow();
            dr.SetField<int>("Number", 1);
            dr.SetField<int>("Code", 12);
            dr.SetField<int>("Unit", 13);

            dt.Rows.Add(dr);

            dr = dt.NewRow();
            dr.SetField<int>("Number", 1);
            dr.SetField<int>("Code", 13);
            dr.SetField<int>("Unit", 7);

            dt.Rows.Add(dr);

            dr = dt.NewRow();
            dr.SetField<int>("Number", 1);
            dr.SetField<int>("Code", 14);
            dr.SetField<int>("Unit", 18);

            dt.Rows.Add(dr);

            var qry = from rw in dt.AsEnumerable()
                      group rw by new {Number = rw["Number"], Code = rw["Code"]}
                      into grouping
                      select
                          new
                              {
                                  grouping.Key.Number,
                                  grouping.Key.Code,
                                  Unit = grouping.Sum(rw => Convert.ToInt32(rw["Unit"]))
                              };

            foreach(var q in qry)
            {
                
            }

Open in new window

0
 

Author Comment

by:VampValdo
ID: 37785960
Hi, thank you.

I can't translate that into VB.NET code. :'(

Do I then have to loop in the foreach and do a new linq that gives me the top 29 records for every record where sampnumber and testcode are the same as the values from the first linq? With a where?
0
 
LVL 20

Expert Comment

by:BuggyCoder
ID: 37785961
Here is sample LINQ using Method Chains(My Preference):-

var qry =
                dt.AsEnumerable()
                    .GroupBy(rw => new {Number = rw["Number"], Code = rw["Code"]})
                    .Select(grouping => new
                                            {
                                                grouping.Key.Number,
                                                grouping.Key.Code,
                                                Unit = grouping.Sum(rw => Convert.ToInt32(rw["Unit"]))
                                            });
                                            

            foreach(var q in qry)
            {
                
            }

Open in new window


In VB :-
Dim qry = dt.AsEnumerable().GroupBy(Function(rw) New With { _
	.Number = rw("Number"), _
	.Code = rw("Code") _
}).[Select](Function(grouping) New With { _
	grouping.Key.Number, _
	grouping.Key.Code, _
	.Unit = grouping.Sum(Function(rw) Convert.ToInt32(rw("Unit"))) _
})



For Each q As var In qry
Next

Open in new window


Used This For Conversion:-
http://converter.telerik.com/
0
Resolve Critical IT Incidents Fast

If your data, services or processes become compromised, your organization can suffer damage in just minutes and how fast you communicate during a major IT incident is everything. Learn how to immediately identify incidents & best practices to resolve them quickly and effectively.

 

Author Comment

by:VampValdo
ID: 37786055
Hi,

This code is not working.

I get the following error:
error
I even tried using sampnumber for the sum (that are all whole numbers)

But I just need a list of the unique values of (sampnumber / testcode).
0
 
LVL 20

Expert Comment

by:BuggyCoder
ID: 37786269
this probably means that it cannot be converted to integer
Just see if its type is integer....

Otherwise use the same type as in your datatable...
0
 
LVL 75

Accepted Solution

by:
käµfm³d   👽 earned 500 total points
ID: 37786328
See if this helps you:

Dim query = From row As DataRow In dt.Rows
            Group row By SampNumber = row.Field(Of Integer)("sampnumber"), TestCode = row.Field(Of Integer)("testcode") Into Group
            Select Group

For Each grp In query
  Dim last29 = grp.Skip(grp.Count() - 29)

  For Each item In last29
    ' do something with last 29 for each grp
  Next
Next

Open in new window

0
 

Author Closing Comment

by:VampValdo
ID: 37786392
Worked like a charm.

Thank you. :-)
0

Featured Post

Space-Age Communications Transitions to DevOps

ViaSat, a global provider of satellite and wireless communications, securely connects businesses, governments, and organizations to the Internet. Learn how ViaSat’s Network Solutions Engineer, drove the transition from a traditional network support to a DevOps-centric model.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
Today I had a very interesting conundrum that had to get solved quickly. Needless to say, it wasn't resolved quickly because when we needed it we were very rushed, but as soon as the conference call was over and I took a step back I saw the correct …

733 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question