C#: Cara Grouping DataTable dengan LINQ

Kali ini kita akan membahas bagaimana membuat group by pada datatable untuk mengitung COUNT dengan menggunakan LINQ.

Sebagai contoh kasus absensi karyawan harian. Tabel sebelah kiri adalah data mentah yang berisi kolom Employee (karyawan) dan Date In (tanggal masuk/absen). Kemudian data tersebut ingin ditampilkan dalam bentuk tabel di sebelah kanan yaitu menampilkan nama karyawan dan total hari masuk. 


Kita langsung saja ke project nya yah. Rani sudah punya 1 project C# window dan tampilan UI nya diatur sebagai berikut:



Kita akan menggunakan LINQ, DataTable, dan membuat satu fungsi untuk mengubah hasil query LINQ menjadi DataTable. maka kita perlu menggunakan class-class sebagai berikut:

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;

Kita akan berikan beberapa code untuk pengaturan UI pada event Form1_Load: 
private void Form1_Load(object sender, EventArgs e)

{
   dataGridView1.AllowUserToAddRows = false;
   button1.Text = "Show Data";
}


Kemudian untuk mengubah hasil query LINQ ke dalam bentuk DataTable perlu sebuah fungsi yang diberinama LINQResultToDataTable sebagai berikut: 

public static DataTable LINQResultToDataTable<T>
    (IEnumerable<T> Linqlist)
{
    DataTable dt = new DataTable();
    PropertyInfo[] columns = null;


    if (Linqlist == null) return dt;

    foreach (T Record in Linqlist)
    {

        if (columns == null)
        {
            columns = ((Type)Record.GetType()).GetProperties();
            foreach (PropertyInfo GetProperty in columns)
            {
                Type colType = GetProperty.PropertyType;

                if ((colType.IsGenericType) &&
                    (colType.GetGenericTypeDefinition()
                       == typeof(Nullable<>)))
                {
                    colType = colType.GetGenericArguments()[0];
                }

                dt.Columns.Add(new DataColumn(GetProperty.Name, colType));
            }
        }

        DataRow dr = dt.NewRow();

        foreach (PropertyInfo pinfo in columns)
        {
            dr[pinfo.Name] = pinfo.GetValue(Record, null) == null ?
                DBNull.Value : pinfo.GetValue
                (Record, null);
        }

        dt.Rows.Add(dr);
    }
    return dt;
}



Terakhir query dengan LINQ akan kita buat di bawah event Button1_Click.

private void Button1_Click(object sender, EventArgs e)
{
    // datatable
    DataTable table = new DataTable();
    table.Columns.Add("Employee", typeof(string));
    table.Columns.Add("DateIn", typeof(DateTime));

    //input data
    table.Rows.Add("Luki", Convert.ToDateTime("2022-04-01"));
    table.Rows.Add("Luki", Convert.ToDateTime("2022-04-02"));
    table.Rows.Add("Dona", Convert.ToDateTime("2022-04-01"));
    table.Rows.Add("Dona", Convert.ToDateTime("2022-04-02"));
    table.Rows.Add("Dona", Convert.ToDateTime("2022-04-03"));
    table.Rows.Add("Emil", Convert.ToDateTime("2022-04-01"));
    table.Rows.Add("Emil", Convert.ToDateTime("2022-04-02"));
    table.Rows.Add("Tina", Convert.ToDateTime("2022-04-01"));

    // LINQ query
    var query = from row in table.AsEnumerable()
    group row by row.Field<string>("Employee") into Employee
    orderby Employee.Key
    select new
              {
                    Employee = Employee.Key,
                    TotalIn = Employee.Count()
                };

    dataGridView1.DataSource = LINQResultToDataTable(query);
}


Code lengkap pada Form1.cs:

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;

namespace LinqGroup
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            dataGridView1.AllowUserToAddRows = false;
            button1.Text = "Show Data";
        }

        public static DataTable LINQResultToDataTable<T>
            (IEnumerable<T> Linqlist)
        {
            DataTable dt = new DataTable();
            PropertyInfo[] columns = null;

            if (Linqlist == null) return dt;

            foreach (T Record in Linqlist)
            {

                if (columns == null)
                {
                    columns = ((Type)Record.GetType()).GetProperties();
                    foreach (PropertyInfo GetProperty in columns)
                    {
                        Type colType = GetProperty.PropertyType;

                        if ((colType.IsGenericType) &&
                            (colType.GetGenericTypeDefinition()
                               == typeof(Nullable<>)))
                        {
                            colType = colType.GetGenericArguments()[0];
                        }

                        dt.Columns.Add(new DataColumn(GetProperty.Name, colType));
                    }
                }

                DataRow dr = dt.NewRow();

                foreach (PropertyInfo pinfo in columns)
                {
                    dr[pinfo.Name] = pinfo.GetValue(Record, null) == null ?
                        DBNull.Value : pinfo.GetValue
                        (Record, null);
                }

                dt.Rows.Add(dr);
            }
            return dt;
        }

        private void Button1_Click(object sender, EventArgs e)
        {
            // datatable
            DataTable table = new DataTable();
            table.Columns.Add("Employee", typeof(string));
            table.Columns.Add("DateIn", typeof(DateTime));

            //input data
            table.Rows.Add("Luki", Convert.ToDateTime("2022-04-01"));
            table.Rows.Add("Luki", Convert.ToDateTime("2022-04-02"));
            table.Rows.Add("Dona", Convert.ToDateTime("2022-04-01"));
            table.Rows.Add("Dona", Convert.ToDateTime("2022-04-02"));
            table.Rows.Add("Dona", Convert.ToDateTime("2022-04-03"));
            table.Rows.Add("Emil", Convert.ToDateTime("2022-04-01"));
            table.Rows.Add("Emil", Convert.ToDateTime("2022-04-02"));
            table.Rows.Add("Tina", Convert.ToDateTime("2022-04-01"));

            // LINQ query
            var query = from row in table.AsEnumerable()
                        group row by row.Field<string>("Employee") into Employee
                        orderby Employee.Key
                        select new
                        {
                            Employee = Employee.Key,
                            TotalIn = Employee.Count()
                        };

            dataGridView1.DataSource = LINQResultToDataTable(query);
        }
    }
}

Kemudian mari kita coba run debug.




Post a Comment

0 Comments