Joining Values Of Two Columns From DataTable - c#

Joining Values Of Two Columns From DataTable
Two columns make it in one columns from datatable
my datatable is
TagNumber, LogNumber Combined
124 1 2
125 1 3
126 2 4
o/p:
TagNumber
124 ~1~2
125 ~1~3
126 ~2~4
combined column is merge from column0 and column1
i dont understand hw can i do please write sample of code
I dont have experience on linq .
I add column bt hw can i merge two columns in that one columns
I got answer:
For i As Integer = 0 To dstemp.Tables(0).Rows.Count - 1
dstemp.Tables(0).Rows(i)(0) = dstemp.Tables(0).Rows(i)("TagNumber") & "~" & dstemp.Tables(0).Rows(i)("LogNumber") & "~" & dstemp.Tables(0).Rows(i)("Combined")
next

Try doing it like this.
dtTwoItems.Columns.Add("Combined", typeof(string), "TagNumber+'/'+LogNumber");

Ok if you really want to do this then you have create a extra DataTable with Three Columns:
TagNumber, LogNumber Combined:
as below:
private DataTable CreateDataTableColumns()
{
DataTable dtThreeItems = new DataTable();
dtThreeItems.Columns.Add("TagNumber", typeof(String));
dtThreeItems.Columns.Add("LogNumber", typeof(String));
dtThreeItems.Columns.Add("Combined", typeof(String));
return dtThreeItems;
}
Now iterate the old datatable as below to get combined value:
foreach (DataRow dr in dtTwoItems.Rows)
{
row = dtThreeItems.NewRow();
row["TagNumber"] = dr["TagNumber"].ToString();
row["LogNumber"] = dr["LogNumber"].ToString();
row["Combined"] = dr["TagNumber"].ToString()+"/"+dr["LogNumber"].ToString() ;
dtThreeItems.Rows.Add(row);
}
Thats All

DataTable is like a container.
It is not proper to join tables.
I recommend you'd use linq.

Did you try to Add new Column to DataTable and then iterate through Each Row to put value by combining them?
EDIT: I Am not sure if Linq or Datatable query have some inbuilt feature to do this, but simple solution is what I tell. Or if you are filling your datatable from any SQL Query based database, then write a SQL that has third column with merged value using concat of columns.
Edit2:
foreach (Datarow r in myTable.Rows) {
r["Newcolumn"] = Convert.ToString(r["c1"]) + "/" + Convert.ToString(r["c2"]);
}

Related

How to merge two columns from a datatable and make it single column using select and CopyToDataTable functions

I am reading CSV file into datatable.
In my datatable I have 4 columns date, time, value1 and value2.
Date Time VALUE1 VALUE2
05/16/2019 15:08:02 2.01 1.01
05/16/2019 15:08:03 4.02 1.02
05/16/2019 15:08:04 5.03 1.03
I want to merge date and time columns in the datatable into a single column called datetime and need to merge date and time values with comma.
I want like below.
DateTime VALUE1 VALUE2
05/16/2019,15:08:02 2.01 1.01
05/16/2019,15:08:03 4.02 1.02
05/16/2019,15:08:04 5.03 1.03
How to achieve it?
Please help me.
You need to declare one more temporary table to hold columns in table and then by using .Select predicate in linq you can flatten your existing datable rows to newly created table with .CopyToDataTable() extension.
DataTable _dt = new DataTable();
_dt.Columns.Add("DateTime", typeof(string));
_dt.Columns.Add("VALUE1", typeof(double));
_dt.Columns.Add("VALUE2", typeof(double));
DataTable result = dt.AsEnumerable()
.Select(x =>
{
var r = _dt.NewRow();
r["DateTime"] = Convert.ToString(x["Date"]) + ", " + Convert.ToString(x["Time"]);
r["VALUE1"] = Convert.ToDouble(x["VALUE1"]);
r["VALUE2"] = Convert.ToDouble(x["VALUE2"]);
return r;
})
.CopyToDataTable();
In the above code snippet result is a data table that contains flattened output from above LINQ query.
Output:
Try this one.
dt.Columns.Add("DateTime_Merge", typeof(string), "Date+','+Time");
For removing columns
dt.Columns.Remove("Date");
dt.Columns.Remove("Time");

c# all distincts value from datatable

I've found this piece of code that can be used to get all distinct values. But my datatable has 10 columns. The distinctValues only shows the columns I write in the toTable(); Is it possible to use this function, but also show the rest of the columns?
DataView view = new DataView(table);
DataTable distinctValues = view.ToTable(true, "Column1", "Column2");
Unless those columns you mention are the full key to the table, there is no guarantee that for a particular combination of those two columns the other columns will have exactly one value.
And if they were the key, then there would be no need to use a "distinct" filter.
You can use Linq-To-DataTable
var distinct = from row in table.AsEnumerable()
group row by new
{
Col1 = row.Field<string>("Column1"),
Col2 = row.Field<string>("Column2")
} into Group
select Group.First()
DataTable tblDistinct = distinctRows.CopyToDataTable();
(assuming that you just want an arbitrary row[the first])

making rows distinct and showing all the columns

In my project there are two datatables dtFail and dtFailed (dtFailed has nothing but column names declarations). dtFail has duplicate "EmployeeName" column values. so i took a dataview dvFail and did the process to make them distinct as shown in the below code:
dtFail
I tried the below code:
DataView dvFail = new DataView(dtFail);
dtFail = dvFail.ToTable(true, "EmployeeName"); //showing only one column in dtFail
dtFailed (only one column)
If i do like below
DataView dvFail = new DataView(dtFail);
dtFail = dvFail.ToTable(true, "EmployeeName","EmployeeRole","Status");
dtFailed (showing but with duplicate rows)
Then the datatable dtFailed is storing duplicate "EmployeeName" also.
Please Help
Thanks in Advance.
Try this query-
DataTable distinctTable = originalTable.DefaultView.ToTable( /*distinct*/ true);
For more info hit below link-
https://social.msdn.microsoft.com/Forums/en-US/ed9c6a6a-a93e-4bf5-a892-d8471b84aa3b/distinct-in-datatable-or-dataview?forum=adodotnetdataset
I hope this would have helped you.
SOLUTION 1:
Based on the question my understanding is, we need to consider duplicates based on EmployeeName and we need not worry about other columns. If that is the case below solution works better.
foreach(DataRow r in dtFail.AsEnumerable())
{
if (!dt1.AsEnumerable().Any(r1 => r1["EmployeeName"] == r["EmployeeName"]))
{
// if you don't want to copy entire row create new DataRow
// with required fields and add that row.
dt1.Rows.Add(r.ItemArray);
}
}
if you want you can put dt1 back to dtFail.
SOLUTION 2:
If we need to consider distinct rows I prefer below solution.
var temp = dtFail.AsEnumerable().Distinct();
dtFail = temp.CopyToDataTable();
I'm not sure it will be helpful or not. As far as I get from your question that you want EmployeeName to be distinct irrelevant to other columns. But if you do ToTable and turn on the distinct flag it will give all the distinct rows, doesn't matter how many columns are involved there. So if you mention only EmployeeName it will obviously give you distinct EmployeeNames, not all the columns associated with it.
So, thats what I did, initially select only the distinct EmployeeName columns and put it into a temp DataTable dtt.
DataTable dtt = dvFail.DefaultView.ToTable(true, "EmployeeName");
Secondly I've created another temp DataTable where we put the segregated rows from the main DataTable dtFail and set the column names manually.
DataTable TempDataTable = new DataTable();
DataTable dtFailed = new DataTable();
Prepare the columns in the dtFailed DataTable.
if (dtFailed.Columns.Count == 0)
{
dtFailed.Columns.Add("EmployeeName");
dtFailed.Columns.Add("EmployeeRole");
dtFailed.Columns.Add("Status");
dtFailed.Columns.Add("Date");
}
Loop through the distinct EmployeeName dtt DataTable and match the EmployeeName and keep that selected first row in the TempDataTable. Finally all rows transferred into the dtFailed.
for (int j = 0; j < dtt.Rows.Count; j++)
{
string EmployeeName = dtt.Rows[j]["EmployeeName"].ToString();
TempDataTable = dvFail.Select("EmployeeName = " + EmployeeName).CopyToDataTable();
dtFailed.Rows.Add(TempDataTable.Rows[0].ItemArray);
}

How to remove the merged datatable from the datatable using C#.Net?

I have two datatables D1 and D2.
I merged the datatable D2 with D1 as follows:
D1.Merge(D2);
But now, I want to remove the DataTable D2 from the D1. How to achieve this?
This may not be the most beautiful solution, but you can consider adding a distinctive column to your tables. I set those values by hand, but for example if your datatables are filled from a SQL query, you can easily add that distinctive column in those queries and use them accordingly.
D1.Columns.Add("ORIGINAL_DATATABLE_NAME", typeof(int));
D2.Columns.Add("ORIGINAL_DATATABLE_NAME", typeof(int));
foreach(DataRow row in D1.Rows)
row["ORIGINAL_DATATABLE_NAME"] = 1;
foreach(DataRow row in D2.Rows)
row["ORIGINAL_DATATABLE_NAME"] = 2;
D1.Merge(D2);
DataRow[] rows = D1.Select("ORIGINAL_DATATABLE_NAME=1", "");
DataSet ds = new DataSet();
ds.Merge(rows, false, MissingSchemaAction.Add);
ds.Tables[0].Columns.Remove("ORIGINAL_DATATABLE_NAME");

Parsing DataTable from flat table to normailze table

I have a requirement for B2B integration, I will reading flat table from dataset and parse to a normalize form of datatable.
I will have reapting colums in the datatable
Sample Data
Invoice num Amount LineNum Line Amout Ledger
INV1 100 1 50 11101
INV1 100 2 50 25631
rows will repeat with different invoices
How can distinctly select into new datatable ? using ADO.NET
I want to parse the data into following format
Header Table
Invoice num Amount
INV1 100
Line Table
Invoice num LineNum Line Amout Ledger
INV1 1 50 11101
INV1 2 50 25631
QUESTION : I dont know what would be the best way to bring the above format ? I see examples usign linq , DataTable, Views ? I looking for a code snippet.
OK, to start the problem, I am working with a DataTable and data defined as follows. Change names and types to suit your needs.
// I am building this table in code just for the purposes of this answer.
// If you already have your data table, ignore!
DataTable salesTable = new DataTable();
salesTable.Columns.Add("InvoiceNum", typeof(string));
salesTable.Columns.Add("Amount", typeof(decimal));
salesTable.Columns.Add("LineNum", typeof(int));
salesTable.Columns.Add("LineAmount", typeof(decimal));
salesTable.Columns.Add("Ledger", typeof(string));
// This is also just to populate data for the sample.
// Omit as you already have your data.
salesTable.Rows.Add("INV1", 100M, 1, 50M, "11101");
salesTable.Rows.Add("INV1", 100M, 1, 50M, "25631");
Notice that I'm using the overload of .Rows.Add that accepts a params object[] array. The values I'm passing in are in the order and type of the columns they should populate. The code below uses the same approach.
First thing I want to do is define the tables for your new normalized format. First, the header table.
DataTable headerTable = new DataTable();
headerTable.Columns.Add("InvoiceNum", typeof(string));
headerTable.Columns.Add("Amount", typeof(decimal));
And then the line item table.
DataTable lineTable = new DataTable();
lineTable.Columns.Add("InvoiceNum", typeof(string));
lineTable.Columns.Add("LineNum", typeof(int));
lineTable.Columns.Add("LineAmount", typeof(decimal));
lineTable.Columns.Add("Ledger", typeof(string));
After this, I'm going to utilize LINQ to group the original sales table based on the invoice number.
var groupedData = from row in salesTable.AsEnumerable()
group row by row.Field<string>("InvoiceNum") into grp
select grp;
After this, it's just a matter of iterating over the groups and adding the data to the new tables.
foreach (var invoiceGroup in groupedData)
{
string invoiceNumber = invoiceGroup.Key;
decimal amount = invoiceGroup.First().Field<decimal>("Amount");
headerTable.Rows.Add(invoiceNumber, amount);
foreach (DataRow row in invoiceGroup)
{
lineTable.Rows.Add(
invoiceNumber,
row.Field<int>("LineNum"),
row.Field<decimal>("LineAmount"),
row.Field<string>("Ledger")
);
}
}
And now you have your data in the normalized format you prefer. Again, change relevant column names and data types to suit your needs.

Categories

Resources