Let's say I have two DataTables DT1 and DT2 with a single row.
DT1 has 3 columns: Col1, Col2, and Col3
and
DT2 has 2 columns: ColA, ColB.
Is it possible to join these two DataTables horizontally so I get Col1, Col2, Col3, ColA, and ColB?
I thin you have to add new columns and copy data either in third table or in one of the existing table
DataTable dt1 = new DataTable();
dt1.Columns.Add("col1", typeof(string));
dt1.Columns.Add("col2", typeof(string));
dt1.Columns.Add("col3", typeof(string));
DataTable dt2 = new DataTable();
dt2.Columns.Add("cola", typeof(string));
dt2.Columns.Add("colb", typeof(string));
object[] row = {'1', '2', '3'};
dt1.Rows.Add(row);
object[] row1 = { 'a', 'b' };
dt2.Rows.Add(row1);
// Create columns in dt1
dt1.Columns.Add("cola", typeof(string));
dt1.Columns.Add("colb", typeof(string));
// Copy data from dt2
dt1.Rows[0]["cola"] = dt2.Rows[0]["cola"];
dt1.Rows[0]["colb"] = dt2.Rows[0]["colb"];
So long as you simply want a collection you can bind to you can do the following:
var results = from rs1 in table1.Rows.Cast<DataRow>()
join rs2 in table2.Rows.Cast<DataRow>() on rs1.Field<int>("col1") equals rs2.Field<int>("colA")
select new { col1 = rs1.Field<int>("col1"), col2 = rs1.Field<string>("col3"), col3 = rs1.Field<string>("col3"), colA = rs1.Field<int>("colA"), colB = rs1.Field<string>("colB") };
You would not get a DataTable but an IEnumerable<T> collection of anonymous type objects as defined in the select statement. Obvoiusly i have just guessed the join criteria and the data type of the columns so you would have to specify those as appropriate for your actual data.
Related
I have defined a dataTable Like this
DataTable dtFinal = new DataTable();
dtFinal.Columns.Add("AVNR", typeof(int));
dtFinal.Columns.Add("Substation", typeof(string));
dtFinal.Columns.Add("ColumnTitle", typeof(string));
dtFinal.Columns.Add("S6_NAME", typeof(string));
dtFinal.Columns.Add("Voltage", typeof(string));
dtFinal.Columns.Add("Wert", typeof(decimal));
and I make a join between two tables to have a result set
var results = from table1 in dtTimeListTable.AsEnumerable()
join table2 in readyDataTable.AsEnumerable() on (decimal)table1["Avnr"] equals (int)table2["Avnr"]
select new
{
AVNR = (int)table2["AVNR"],
Substation = (string)table2["Substation"],
ColumnTitle = (string)table2["ColumnTitle"],
S6_NAME = (string)table2["S6_NAME"],
Voltage = (string)table2["Voltage"],
Wert = (decimal)table1["Wert"]
};
to fill datatable up I do the following:
dtFinal.Rows.Add(results.ToArray());
but I'll get a error liek this
input array is longer than the number of columns in this table
both datatable have 6 columns, what could be the problem?
DataRowCollection.Add is a method to add a single DataRow but you are trying to add all rows.
You need a loop:
foreach(var x in query)
dtFinal.Rows.Add(x.AVNR, x.Substation, x.ColumnTitle, x.S6_NAME, x.Voltage, x.Wert);
You could build the object[] for each DataRow also in this way:
var joinedRows = from table1 in dtTimeListTable.AsEnumerable()
join table2 in readyDataTable.AsEnumerable() on (decimal) table1["Avnr"] equals (int) table2["Avnr"]
select new { r1 = table1, r2 = table2 };
foreach (var x in joinedRows)
{
object[] fields =
{
x.r2.Field<int>("AVNR"), x.r2.Field<string>("Substation"), x.r2.Field<string>("ColumnTitle"),
x.r2.Field<int>("S6_NAME"), x.r2.Field<string>("Voltage"), x.r1.Field<decimal>("Wert"),
};
dtFinal.Rows.Add(fields);
}
I have this sql query and I want to convert it to linq.
SELECT [Scheme_Code], [FundFamily], [Scheme_Name], MAX([Date]) as LastDate
FROM [MFD].[dbo].[MFDatas]
GROUP BY [Scheme_Code], [Scheme_Name], [FundFamily]
ORDER BY [Scheme_Code]
I want to check last date and if it's latest then I have to mark it as 'live'?
Since you want to copy results to DataTable, this query does what specified in your Sql query and copies results to DataTable.
DataTable dt = new DataTable();
dt.Columns.Add("Scheme_Code", typeof(string));
dt.Columns.Add("Scheme_Name", typeof(string));
dt.Columns.Add("FundFamily", typeof(string));
dt.Columns.Add("LastDate", typeof(DateTime));
var table = MFDatas.GroupBy(g=> new { Scheme_Code, Scheme_Name, FundFamily})
.Select(s=>
{
var row = dt.NewRow();
row["Scheme_Code"] = s.Key.Scheme_Code,
row["Scheme_Name"] = s.Key.Scheme_Name,
row["FundFamily"] = s.Key.FundFamily,
row["LastDate"] = s.Max(m=>m.Date)
})
.OrderBy(o=>o.Field<string>("Scheme_Code"))
.Distinct()
.CopyToDataTable();
is there any way to replace all occurrences of a value in a data table with another value from a different data table.for example I have two data table one has Itemid and another has itemid and item name.I need to replace item id in first data table with the item name from the second data table..Is there any possible way to replace all occurances at one go or should i go for the usual loop method and use Datatable.Select method.Please help.Thanks in advance.
What about this? (I realise it is a loop - but very compact and any built in method would loop anyway, just behind the scenes)
//Build first Test DT
DataTable dt1 = new DataTable();
dt1.Columns.Add("itemID", typeof(string));
//Build Second Test DT
DataTable dt2 = new DataTable();
dt2.Columns.Add("itemID", typeof(string));
dt2.Columns.Add("itemName", typeof(string));
//aad 3 DataRows to first DT - ID only
DataRow dt1_1 = dt1.NewRow();
dt1_1["itemID"] = "1";
DataRow dt1_2 = dt1.NewRow();
dt1_2["itemID"] = "2";
DataRow dt1_3 = dt1.NewRow();
dt1_3["itemID"] = "3";
dt1.Rows.Add(dt1_1);
dt1.Rows.Add(dt1_2);
dt1.Rows.Add(dt1_3);
//aad 3 DataRows to first DT - ID & Name
DataRow dt2_1 = dt2.NewRow();
dt2_1["itemID"] = "1";
dt2_1["itemName"] = "ItemOne";
DataRow dt2_2 = dt2.NewRow();
dt2_2["itemID"] = "2";
dt2_2["itemName"] = "ItemTwo";
DataRow dt2_3 = dt2.NewRow();
dt2_3["itemID"] = "3";
dt2_3["itemName"] = "ItemThree";
dt2.Rows.Add(dt2_1);
dt2.Rows.Add(dt2_2);
dt2.Rows.Add(dt2_3);
////////////////////////////////////////////////////////
//replacing code - quite comact - assumed itemId is PK//
////////////////////////////////////////////////////////
foreach (DataRow dr in dt1.Rows)
{
string strSelect = "[itemID] = '"+ dr["itemID"] +"'";
DataRow[] myRow = dt2.Select(strSelect);
if (myRow.Length == 1)
{
dr["itemID"] = myRow[0]["itemName"];
}
}
/////////////////////////////////////////////////////////////////
//dt1 now has itemOne, itemTwo and itemThree instead of 1, 2, 3//
/////////////////////////////////////////////////////////////////
With MySQL I would try:
UPDATE table1 t1, table2 t2
SET t1.itemid = t2.itemname
WHERE t1.itemid = t2.itemid
With MS-SQL I would try
UPDATE t1
SET t1.itemid = t2.itemname
FROM table1 t1 INNER JOIN table2 t2
ON t1.itemid = t2.itemid
have a Dataset Ds1 and dataset Ds2 , DS1 has Product_ID, product information and ds2 has Product_ID, product_type.
for the matching product_id, I want to add the Product_tye column from ds2 to ds1 .
Note: Product_id is not primary key in ds 1, the result set has many products with same product_id. In ds 2, product_id is unique. also, those datatbles are from two different databases on different servers and has different credentials , so cant use sql joins.
I tried to use linq to acheive this, but not getting the desired output, please correct me if i am mising something .
DataTable dt1 = new DataTable();
DataTable dt2 = new DataTable();
//After both the datatble has values, using linq to add datatble columsn,
DataTable result = (from t1 in dt1.AsEnumerable()
join t2 in dt2.AsEnumerable() on t1.Field<string>("productID") equals t2.Field<string>("productID")
select t1).CopyToDataTable();
Selecting both tables
DataTable result = (from t1 in dt1.AsEnumerable()
join t2 in dt2.AsEnumerable() on t1.Field<string>("productID")
equals t2.Field<string>("productID")
select new {t1,t2}
).CopyToDataTable();
OR Selecting selected columns
DataTable result = (from t1 in dt1.AsEnumerable()
join t2 in dt2.AsEnumerable() on t1.Field<string>("productID")
equals t2.Field<string>("productID")
select new {
productId = t1.productID,
col2 = t1.col2,...,
productType = t2.pruductType
).CopyToDataTable();
NOTE: I think productID type should be int type so replace string with int in that case
I have just created you a simple example, what you have to do is to change column names from my code, with your own:
DataTable table1 = new DataTable();
DataTable table2 = new DataTable();
table1.Columns.Add("id", typeof(int));
table1.Columns.Add("name", typeof(string));
table2.Columns.Add("id", typeof(int));
table2.Columns.Add("age", typeof(int));
table1.Rows.Add(1, "mitja");
table1.Rows.Add(2, "sandra");
table1.Rows.Add(3, "nataška");
table2.Rows.Add(1, 31);
table2.Rows.Add(3, 24);
table2.Rows.Add(4, 46);
DataTable targetTable = table1.Clone();
//create new column
targetTable.Columns.Add("age");
var results = from t1 in table1.AsEnumerable()
join t2 in table2.AsEnumerable() on t1.Field<int>("id") equals t2.Field<int>("id")
select new
{
ID = (int)t1["id"],
NAME = (string)t1["name"],
AGE = (int)t2["age"]
};
foreach (var item in results)
targetTable.Rows.Add(item.ID, item.NAME, item.AGE);
Be careful on defining type of variables (int, string, ...) in any case!!!
Hope it helps.
I am having two datatables and my basic need is to know whether the value in a datatable is exist on the another datatable.
My first datatable will contains data like this (id,name,unit)
Second one like this (id,value).
The values may be like this
1-A-b,2-B-c,3-X-d for first one
and 1-2,3,5 for second one. Here 1 and 3 are exsting.How can I find the corresponding values using the id.
this should work;
var table = new DataTable();
table.Columns.Add("id", typeof(int));
table.Columns.Add("name");
table.Columns.Add("unit");
var table2 = new DataTable();
table2.Columns.Add("id", typeof(int));
table2.Columns.Add("value");
table.Rows.Add(1, "a Name", "a Unit");
table.Rows.Add(2, "other", "other");
table2.Rows.Add(1, "value");
table2.Rows.Add(4, "other");
var result = table.AsEnumerable().Join(table2.AsEnumerable(), r1 => r1.Field<int>("id"), r2 => r2.Field<int>("id"),
(r1, r2) => new {Id = r1.Field<int>("id"), Value = r2.Field<string>("value") }).ToList();
foreach (var r in result)
Console.WriteLine(r.Id + "|"+ r.Value);