Home > Software engineering >  Linq with datatable with two counts c#
Linq with datatable with two counts c#

Time:09-19

I would like to have two different counts in a single query; I wrote it with SQL Server with the COUNT function as

COUNT(CASE WHEN Status = 'opened' THEN 1 ELSE NULL)

which returns my desired count.

However, in the current situation, I have datatable and am not sure if the above two counts are possible in Linq.

My data is as below.

Email      Status 
------------------
email1     opened
email1     opened
email2     clicked
email2     clicked
email2     clicked
email1     clicked
email2     opened

The output needs to be:

Email      Opened      Clicked
-------------------------------
email1      2             1
email2      1             3

CodePudding user response:

Using C# Linq try something like this:

var test =  context.stats.GroupBy(x=> x.Email).Select(groupedBy=> new {
            Email = groupedBy.FirstOrDefault().Email,
            Opened = groupedBy.Where(y=> y.Status == "opened").Count(),
            Clicked = groupedBy.Where(y=> y.Status == "clicked").Count()
        });

CodePudding user response:

You want a pivot table. See code below :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;


namespace ConsoleApplication40
{
    class Program
    {

        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("Email", typeof(string));
            dt.Columns.Add("Status", typeof(string));

            dt.Rows.Add(new object[] { "email1", "opened"});
            dt.Rows.Add(new object[] { "email1", "opened" });
            dt.Rows.Add(new object[] { "email2", "clicked" });
            dt.Rows.Add(new object[] { "email2", "clicked" });
            dt.Rows.Add(new object[] { "email2", "clicked" });
            dt.Rows.Add(new object[] { "email1", "clicked" });
            dt.Rows.Add(new object[] { "email2", "opened" });


            string[] statusTypes = dt.AsEnumerable().Select(x => x.Field<string>("Status")).Distinct().OrderBy(x => x).ToArray();
            var groups = dt.AsEnumerable().GroupBy(x => x.Field<string>("Email")).ToList();

            DataTable pivot = new DataTable();
            pivot.Columns.Add("Email",typeof(string));
            foreach(string statusType in statusTypes)
            {
                pivot.Columns.Add(statusType, typeof(int));
            }

            foreach(var group in groups)
            {
                DataRow row = pivot.Rows.Add();
                row["Email"] = group.Key;
                foreach(string statusType in statusTypes)
                {
                    row[statusType] = group.Where(x => x.Field<string>("Status") == statusType).Count();
                }
            }
        }
    }
}
  • Related