c# simple group by linq example

Hello all, I am taking datatables and splitting them into different datatables and doing so successfully as seen below

List<DataTable> result = dt.AsEnumerable()
            .GroupBy(row => row.Field<int>("number"))
            .Select(g => g.CopyToDataTable())
            .ToList();

However what I want to do is create a this same splitting of table but by total records
so say i have DataTable dt that has 4000 records, i want to split like above into 4 different databables, now based upon a row value but just the number of rows so I would get

result[0] = datatable that had 1000 records
result[1] = datatable that had next 1000 records
result[2] = datatable that had next 1000 records
result[3] = datatable that had next 1000 records

it is the group by
 .GroupBy(row => row.Field<int>("number"))
element i believe i have to change as right now it is grouping by identical values of the row Field, where i want to group by number of records
LVL 4
Brant SnowAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

it_saigeDeveloperCommented:
You want to use a combination of .Skip() and .Take().

Skip moves past n records
Take returns n records.

Better yet, you could make some paging extension methods and use those:
static class Extensions
{
	public static IEnumerable<T> GetPage<T>(this IEnumerable<T> source, int index = 0, int size = 10)
	{
		return source.Skip((index > 0) ? (index * size) : 0).Take(size);
	}

	public static IEnumerable<IEnumerable<T>> GetPages<T>(this IEnumerable<T> source, int size = 10)
	{
		return (from range in Enumerable.Range(0, (source.Count() / size) + 1) select source.GetPage(range, size));
	}
}

Open in new window

Example usage -
using System;
using System.Collections.Generic;
using System.Linq;

namespace EE_Q28709213
{
	class Program
	{
		static readonly List<int> values = new List<int>();

		static void Main(string[] args)
		{
			values.AddRange(Enumerable.Range(0, 4578));
			foreach (var value in values.GetPage(2, 1000))
				Console.WriteLine("Value: {0}", value);

			Console.WriteLine(values.GetPages(1000).Count());
			foreach (var page in values.GetPages(1000))
				Console.WriteLine("Page Start: {0}, Page End: {1}", page.First(), page.Last());

			Console.ReadLine();
		}
	}

	static class Extensions
	{
		public static IEnumerable<T> GetPage<T>(this IEnumerable<T> source, int index = 0, int size = 10)
		{
			return source.Skip((index > 0) ? (index * size) : 0).Take(size);
		}

		public static IEnumerable<IEnumerable<T>> GetPages<T>(this IEnumerable<T> source, int size = 10)
		{
			return (from range in Enumerable.Range(0, (source.Count() / size) + 1) select source.GetPage(range, size));
		}
	}
}

Open in new window

Produces the following output -Capture.JPG
-saige-
1

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Brant SnowAuthor Commented:
it_saige I am having problems understanding because i am using DataTables ...
could you assume that

DataTable dt = new DataTable();

then it gets populated with 5000 records.

I want to split this DataTable into 5 seperate DataTables each with 1000 records
0
it_saigeDeveloperCommented:
What is a DataTable but an array of rows.  You can cast the DataTable to an Enumerable by using the AsEnumerable extension method after which you can page it.

Consider the following:
using System;
using System.Collections.Generic;
using System.Linq;
using System.ComponentModel;
using System.Data;

namespace EE_Q28709213
{
	class Program
	{
		static readonly List<Person> people = new List<Person>();

		static void Main(string[] args)
		{
			people.AddRange((from row in Enumerable.Range(0, 4578) select new Person() { Id = row, Name = string.Format("Person{0}", row), IsEating = (row % 2 == 0) }));
			DataTable dt = people.ConvertToDataTable();
			foreach (var value in dt.AsEnumerable().GetPage(2, 1000))
				Console.WriteLine("Value: {0} with id - {1}; is eating - {2}", value["Name"], value["Id"], value["IsEating"]);

			Console.WriteLine(dt.AsEnumerable().GetPages(1000).Count());
			foreach (var page in dt.AsEnumerable().GetPages(1000))
				Console.WriteLine("Page Start: {0}, Page End: {1}", page.First()["Id"], page.Last()["Id"]);

			Console.ReadLine();
		}
	}

	class Person
	{
		public int Id { get; set; }
		public string Name { get; set; }
		public bool IsEating { get; set; }
	}

	static class Extensions
	{
		public static DataTable ConvertToDataTable<T>(this IEnumerable<T> data)
		{
			PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T));
			DataTable table = new DataTable();
			for (int i = 0; i < props.Count; i++)
			{
				PropertyDescriptor prop = props[i];
				if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
					table.Columns.Add(prop.Name, prop.PropertyType.GetGenericArguments()[0]);
				else
					table.Columns.Add(prop.Name, prop.PropertyType);
			}
			object[] values = new object[props.Count];
			foreach (T item in data)
			{
				for (int i = 0; i < values.Length; i++)
					values[i] = props[i].GetValue(item);
				table.Rows.Add(values);
			}
			return table;
		}

		public static IEnumerable<T> GetPage<T>(this IEnumerable<T> source, int index = 0, int size = 10)
		{
			return source.Skip((index > 0) ? (index * size) : 0).Take(size);
		}

		public static IEnumerable<IEnumerable<T>> GetPages<T>(this IEnumerable<T> source, int size = 10)
		{
			return (from range in Enumerable.Range(0, (source.Count() / size) + 1) select source.GetPage(range, size));
		}
	}
}

Open in new window

Which produces the following output -Capture.JPG
-saige-
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.