How to change DataTable Rows to Columns in C# - c#

How to Change dataTable Rows to Columns
DataTable dt=new DataTable();
dt = getData(); //Pull data from source file
I have below format rows in a dataTable.
Now I want change ANC_TYPE rows into columns?
How i can convert into below format ?

You want a pivot table :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication49
{
class Program
{
static void Main(string[] args)
{
DataTable dt = new DataTable();
dt.Columns.Add("OPR_DT", typeof(DateTime));
dt.Columns.Add("OPR_HR", typeof(int));
dt.Columns.Add("ANC_TYPE", typeof(string));
dt.Columns.Add("ANC_REGION", typeof(string));
dt.Columns.Add("MARKET_RUN_ID", typeof(string));
dt.Columns.Add("XML_DATE_ITEM", typeof(string));
dt.Columns.Add("MW", typeof(decimal));
dt.Columns.Add("GROUP", typeof(int));
dt.Rows.Add(new object[] { DateTime.Parse("2/23/2017"), 1, "NR", "AS_CAISO_EXP", "DAM", "NS_CLR_PRC", 0.09, 1});
dt.Rows.Add(new object[] { DateTime.Parse("2/23/2017"), 1, "RD", "AS_CAISO_EXP", "DAM", "RD_CLR_PRC", 2.83, 2 });
dt.Rows.Add(new object[] { DateTime.Parse("2/23/2017"), 2, "NR", "AS_CAISO_EXP", "DAM", "NS_CLR_PRC", 0.01, 3 });
dt.Rows.Add(new object[] { DateTime.Parse("2/23/2017"), 2, "RD", "AS_CAISO_EXP", "DAM", "RD_CLR_PRC", 0.1, 4 });
string[] uniqueAncType = dt.AsEnumerable().Select(x => x.Field<string>("ANC_TYPE")).Distinct().ToArray();
DataTable pivot = new DataTable();
pivot.Columns.Add("OPR_DT", typeof(DateTime));
pivot.Columns.Add("OPR_HR", typeof(int));
pivot.Columns.Add("ANC_REGION", typeof(string));
pivot.Columns.Add("MARKET_RUN_ID", typeof(string));
foreach (string col in uniqueAncType)
{
pivot.Columns.Add(col, typeof(string));
}
var groups = dt.AsEnumerable()
.GroupBy(x => new {
opr_dt = x.Field<DateTime>("OPR_DT"),
opr_hr = x.Field<int>("OPR_HR"),
anc_region = x.Field<string>("ANC_REGION"),
run_id = x.Field<string>("MARKET_RUN_ID")
}).ToList();
foreach (var group in groups)
{
DataRow newRow = pivot.Rows.Add();
newRow["OPR_DT"] = group.Key.opr_dt;
newRow["OPR_HR"] = group.Key.opr_hr;
newRow["ANC_REGION"] = group.Key.anc_region;
newRow["MARKET_RUN_ID"] = group.Key.run_id;
foreach (DataRow ancType in group)
{
newRow[ancType.Field<string>("ANC_TYPE")] = ancType.Field<decimal>("MW");
}
}
}
}
}

Related

How can I create a DataGridView displaying tables in restaurant

Hello, I am codding a restaurant automation to improve myself.
I have a table called tables in the database.
I can fetch data as shown in the left datagridview. but I
could not split into columns like on the right datagridview
I hope I can explain.
private void FrmAnaEkran_Load(object sender, EventArgs e)
{
VerileriGetir();
}
private void VerileriGetir()
{
Veritabani vt = new Veritabani();
vt.ConnectionOpen();
vt.SqlQuery("select * from masalar");
DataTable dt = vt.GetDataTable();
vt.ConnectionClose();
List<masa> masalar = new List<masa>();
foreach (DataRow dr in dt.Rows)
{
masa m = new masa();
m.adi = dr[1].ToString();
masa.ID = Convert.ToInt32(dr[0]);
masalar.Add(m);
}
for (int i = 0; i < masalar.Count; i++)
{
int n = dataGridView1.Rows.Add();
dataGridView1.Rows[n].Cells[0].Value = masalar[i].adi;
}
}
Use GroupBy :
DataTable dt = new DataTable();
dt.Columns.Add("Masa", typeof(string));
dt.Rows.Add(new object[] { "Masa_1" });
dt.Rows.Add(new object[] { "Masa_2" });
dt.Rows.Add(new object[] { "Masa_3" });
dt.Rows.Add(new object[] { "Masa_4" });
dt.Rows.Add(new object[] { "Masa_5" });
dt.Rows.Add(new object[] { "Masa_6" });
dt.Rows.Add(new object[] { "Masa_7" });
dt.Rows.Add(new object[] { "Masa_8" });
dt.Rows.Add(new object[] { "Masa_9" });
dt.Rows.Add(new object[] { "Masa_10" });
dt.Rows.Add(new object[] { "Masa_11" });
dt.Rows.Add(new object[] { "Masa_12" });
dt.Rows.Add(new object[] { "Masa_13" });
var groups = dt.AsEnumerable().Select((x, i) => new {masa = x.Field<string>("Masa"), index = i}).GroupBy(x => x.index / 4);
DataTable dt2 = new DataTable();
dt2.Columns.Add("Column1", typeof(string));
dt2.Columns.Add("Column2", typeof(string));
dt2.Columns.Add("Column3", typeof(string));
dt2.Columns.Add("Column4", typeof(string));
foreach(var group in groups)
{
DataRow newRow = dt2.Rows.Add();
int col = 0;
foreach(var row in group)
{
newRow[col++] = row.masa;
}
}

How can i select multiple table to datagridview?

I'm trying to combine 3 table into 1 datagridview but i want some spesific columns from each table
these are my tables
a.Malzemeler
-Malzeme_ID (PK)
-Malzemeİsmi
-Gram_mL
-Adet
-BirimFiyat
-ToplamFiyat
b.Tarifler
-Tarif_ID (PK)
-Tarif_İsmi
-Talimatlar
c.TariflerveMalzemeler
-ID
-Tarif_ID (FK)
-Malzeme_ID (FK)
-Gram_mL
-Adet
what i want to do is
d.Result
-Tarif_İsmi (From table b)
-Malzeme_İsmi (from table a)
-Gram_mL(From table c)
-Adet (from table c)
-Talimatlar (From Table b)
My select query work on SQL
"SELECT Tarif_İsmi,Malzemeİsmi, TariflerveMalzemeler.Gram_mL, TariflerveMalzemeler.Adet, Talimatlar FROM Malzemeler
JOIN TariflerveMalzemeler ON Malzemeler.Malzeme_ID = TariflerveMalzemeler.Malzeme_ID JOIN Tarifler ON TariflerveMalzemeler.Tarif_ID = Tarifler.Tarif_ID"
but i dont know how to make it work on datagridview ?
Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication166
{
class Program
{
static void Main(string[] args)
{
DataTable Malzemeler = new DataTable();
Malzemeler.Columns.Add("Malzeme_ID", typeof(string));
Malzemeler.Columns.Add("Malzemeİsmi", typeof(string));
Malzemeler.Columns.Add("Gram_mL", typeof(string));
Malzemeler.Columns.Add("Adet", typeof(string));
Malzemeler.Columns.Add("BirimFiyat", typeof(string));
Malzemeler.Columns.Add("ToplamFiyat", typeof(string));
DataTable Tarifler = new DataTable();
Tarifler.Columns.Add("Tarif_ID", typeof(string));
Tarifler.Columns.Add("Tarif_İsmi", typeof(string));
Tarifler.Columns.Add("Talimatlar", typeof(string));
DataTable TariflerveMalzemeler = new DataTable();
TariflerveMalzemeler.Columns.Add("ID", typeof(string));
TariflerveMalzemeler.Columns.Add("Tarif_ID", typeof(string));
TariflerveMalzemeler.Columns.Add("Malzeme_ID", typeof(string));
TariflerveMalzemeler.Columns.Add("Gram_mL", typeof(string));
TariflerveMalzemeler.Columns.Add("Adet", typeof(string));
DataTable Result = new DataTable();
Result.Columns.Add("Tarif_İsmi", typeof(string));
Result.Columns.Add("Malzeme_İsmi", typeof(string));
Result.Columns.Add("Gram_mL", typeof(string));
Result.Columns.Add("Adet", typeof(string));
Result.Columns.Add("Talimatlar", typeof(string));
var joins = from tm in TariflerveMalzemeler.AsEnumerable()
join m in Malzemeler.AsEnumerable() on tm.Field<string>("Malzeme_ID") equals m.Field<string>("Malzeme_ID")
join t in Tarifler.AsEnumerable() on tm.Field<string>("Tarif_ID") equals t.Field<string>("Tarif_ID")
select new { tm = tm, m = m, t = t};
foreach (var j in joins)
{
Result.Rows.Add(new object[] {
j.t.Field<string>("Tarif_İsmi"),
j.m.Field<string>("Malzeme_İsmi"),
j.tm.Field<string>("Gram_mL"),
j.tm.Field<string>("Adet"),
j.t.Field<string>("Talimatlar")
});
}
}
}
}

c# Left joining 2 DataTable

I have 2 DataTables with no primary keys on either table. I need all records in DataTable1 to be left joined with DataTable2. I've solved it a couple of ways but are they performant?
Column2 is the soft "key" and I am trying to populate the column 3 field in DataTable1 from DataTable2.
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
DataTable dt1 = new DataTable();
dt1.Columns.Add("col1", typeof(int));
dt1.Columns.Add("col2", typeof(string));
dt1.Columns.Add("col3", typeof(string));
dt1.Rows.Add(1, "One");
dt1.Rows.Add(1, "Two");
dt1.Rows.Add(3, "Two");
DataTable dt2 = new DataTable();
dt2.Columns.Add("col1", typeof(int));
dt2.Columns.Add("col2", typeof(string));
dt2.Columns.Add("col3", typeof(string));
dt2.Rows.Add(1, "One", "One Description");
dt2.Rows.Add(2, "Two", "Two Description");
//Solution 1
//foreach (DataRow row in dt1.Rows)
//{
// row[2] = dt2.Select("col2='" + row[1] + "'")[0]["col3"];
//}
foreach (DataRow row in dt1.Rows)
{
row[2] = dt2.AsEnumerable().Where(x => x["col2"] == row[1]).FirstOrDefault()[2];
}
dt1.AsEnumerable().ToList().ForEach(x =>
Console.WriteLine(
"col1:{0} col2:{1} col3:{2}"
, x[0], x[1], x[2])
);
}
}
}
Bonus: I tried to copy this into .Net Fiddle but it doesn't seem to like the AsEnumerable on the DataTable. Go .Net Fiddle
You can use LINQ GroupJoin for that:
var result = dt1.Select()
.GroupJoin(dt2.Select(), t1 => t1[1], t2 => t2[1], (t1, t2) => { t1[2] = t2.FirstOrDefault()?[2]; return t1; })
.ToList();

DataRelation in a DataGridView

I have got a DataSet filled with two Tables:
dbSet = new DataSet();
//DataTable and DataRelation
DataTable dtStudent = new DataTable("Student");
//fill datatable 1
dtStudent.Columns.Add("Id", typeof(int));
dtStudent.Columns.Add("Name", typeof(string));
dtStudent.Columns.Add("TownId", typeof(int));
dtStudent.Rows.Add(new object[] { 1, "Arthur", 1 });
dtStudent.Rows.Add(new object[] { 2, "Stefan", 2 });
DataTable dtTown = new DataTable("Town");
dtTown.Columns.Add("Id", typeof(int));
dtTown.Columns.Add("Name", typeof(string));
dtTown.Rows.Add(new object[] { 1, "KW",});
dtTown.Rows.Add(new object[] { 2, "Perg", });
dbSet.Tables.Add(dtStudent);
dbSet.Tables.Add(dtTown);
And then I have got a DataRelation for these two tables.
So I want to print the Student with his ID, Name and the Name of his town.
That's why I create a DataRelation.
//DataRelation
DataColumn parentCol, childCol;
childCol = dbSet.Tables["Town"].Columns["Id"];
parentCol = dbSet.Tables["Student"].Columns["TownId"];
DataRelation dr;
dr = new DataRelation("DataRelation", parentCol, childCol);
dbSet.Relations.Add(dr);
However, when I add the DataSet to my DataGridView I always get the TownId instead of the TownName.
dgv.DataSource = dbSet;
dgv.DataMember = "Student";
You missed only one thing: you need to add the appropriate column to view the data from the master table
dbSet.Tables["Student"].Columns.Add("Town", dbSet.Tables["Town"].Columns["Name"].DataType, "Parent.Name");
Thus, the entire code will look like this:
dbSet = new DataSet();
//DataTable and DataRelation
DataTable dtStudent = new DataTable("Student");
//fill datatable 1
dtStudent.Columns.Add("Id", typeof(int));
dtStudent.Columns.Add("Name", typeof(string));
dtStudent.Columns.Add("TownId", typeof(int));
dtStudent.Rows.Add(new object[] { 1, "Arthur", 1 });
dtStudent.Rows.Add(new object[] { 2, "Stefan", 2 });
DataTable dtTown = new DataTable("Town");
dtTown.Columns.Add("Id", typeof(int));
dtTown.Columns.Add("Name", typeof(string));
dtTown.Rows.Add(new object[] { 1, "KW",});
dtTown.Rows.Add(new object[] { 2, "Perg", });
dbSet.Tables.Add(dtStudent);
dbSet.Tables.Add(dtTown);
//DataRelation
DataColumn parentCol, childCol;
childCol = dbSet.Tables["Town"].Columns["Id"];
parentCol = dbSet.Tables["Student"].Columns["TownId"];
DataRelation dr;
dr = new DataRelation("DataRelation", parentCol, childCol);
dbSet.Relations.Add(dr);
dbSet.Tables["Student"].Columns.Add("Town", dbSet.Tables["Town"].Columns["Name"].DataType, "Parent.Name");
//Datagridview
dgv.DataSource = dbSet;
dgv.DataMember = "Student";

Datatable group and pivot

I have a DT with following structure
unit | value | date
-------------------------
A | 2 | 01-01-2000
B | 3 | 01-01-2000
A | 4 | 02-01-2000
I would like to transform it into following
| A | B
---------------------------
01-01-2000 | 2 | 3
02-01-2000 | 4 |
What would be the fastest way to achieve this?
EDIT:
I have implemented a function for pivot, which gives me the following:
| A | B | A
--------------------------------------
value | 2 | 3 | 4
date |01-01-2000|01-01-2000|02-01-2000
But in this case I am missing grouping by columns.
By 'fastest' I mean possibly shortest code to achieve this (LINQ?). Or perhaps pivot can be achieved simultaneously in the same query?
Try this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
DataTable dt = new DataTable();
dt.Columns.Add("unit", typeof(string));
dt.Columns.Add("value", typeof(int));
dt.Columns.Add("date", typeof(DateTime));
dt.Rows.Add(new object[] { "A",2, DateTime.Parse("01-01-2000")});
dt.Rows.Add(new object[] { "B",3, DateTime.Parse("01-01-2000")});
dt.Rows.Add(new object[] { "A",4, DateTime.Parse("02-01-2000")});
string[] uniqueUnits = dt.AsEnumerable().Select(x => x.Field<string>("unit")).Distinct().ToArray();
DataTable dt1 = new DataTable();
dt1.Columns.Add("date", typeof(DateTime));
foreach (string unit in uniqueUnits)
{
dt1.Columns.Add(unit, typeof(int));
}
var groups = dt.AsEnumerable().GroupBy(x => x.Field<DateTime>("date"));
foreach (var group in groups)
{
DataRow newRow = dt1.Rows.Add();
foreach (DataRow row in group)
{
newRow["date"] = group.Key;
newRow[row.Field<string>("unit")] = row.Field<int>("value");
}
}
}
}
}
It's more lines of code but can be done with only one loop as well:
DataTable dt1 = new DataTable();
dt1.Columns.Add(new DataColumn("unit",typeof(string)));
dt1.Columns.Add(new DataColumn("value",typeof(int)));
dt1.Columns.Add(new DataColumn("date",typeof(DateTime)));
dt1.Rows.Add(new object[] { "A", 2, DateTime.Parse("01-01-2000") });
dt1.Rows.Add(new object[] { "B", 3, DateTime.Parse("01-01-2000") });
dt1.Rows.Add(new object[] { "A", 4, DateTime.Parse("02-01-2000") });
DataTable dt2 = new DataTable();
dt2.Columns.Add(new DataColumn("date", typeof(DateTime)));
dt2.PrimaryKey = new DataColumn[] { dt2.Columns["date"], };
List<string> cols = new List<string>();
List<DateTime> ds = new List<DateTime>();
foreach (DataRow dr1 in dt1.Rows)
{
string unit = dr1["unit"].ToString();
if (!cols.Contains(unit))
{
dt2.Columns.Add(new DataColumn(unit, typeof(int)));
cols.Add(unit);
}
DateTime pkDate = (DateTime)dr1["date"];
if (!ds.Contains(pkDate))
{
ds.Add(pkDate);
DataRow dr = dt2.NewRow();
dr["date"] = dr1["date"];
dr[unit] = dr1["value"];
dt2.Rows.Add(dr);
}
else
{
dt2.Rows.Find(pkDate)[unit] = dr1["value"];
}
}

Categories

Resources