merge 2 datatable - c#

I have 2 Datatable dt and dt2
var dt = MultiCheckCombo3.GetAllChechedBox();
var dt2 =manager.GetAllStudents(student_id, classid);
In the first table dt are two columns "id_staff" and "name_staff"
In the second table are several columns but 2 of them repeat "id_staff" and "name_staff"
I want to create a new DataTable with the fields "id_staff" and "name_staff" common DataTable dt and dt2
how joined these tables?
dt3= dt+dt2

You can use Linq to join the two tables. See the following example.
Code from the article:
var innerGroupJoinQuery =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
select new { CategoryName = category.Name, Products = prodGroup };

Have a look at the DataTable.Merge method:
This link from Microsoft has an example of how to do this

If dt and dt2 are DataTables, you can use datatable merge.
DataTable dt3 = dt.Copy()
dt3.Merge(dt2, false, MissingSchemaAction.Ignore)

Maybe something like this:
var dt=new DataTable();
dt.Columns.Add("id_staff",typeof(int));
dt.Columns.Add("name_staff",typeof(string));
var dt2=new DataTable();
dt2.Columns.Add("id_staff",typeof(int));
dt2.Columns.Add("name_staff",typeof(string));
dt.Rows.Add(1,"test");
dt2.Rows.Add(2,"test2");
var result=
(
from datatable1 in dt.AsEnumerable()
select new
{
id_staff=datatable1.Field<int>("id_staff"),
name_staff=datatable1.Field<string>("name_staff")
}
).Concat
(
from datatable2 in dt2.AsEnumerable()
select new
{
id_staff=datatable2.Field<int>("id_staff"),
name_staff=datatable2.Field<string>("name_staff")
}
);

Related

update one datatable from another after comparing primary key of both

I have two datatables and each has different 70-80 columns. I want to update the values of one datatable field with other datatable field values which are matching after comparing the primary keys of both in c#.
suppose I have one data table dt1 contains rows and 60 columns.
I have another datatable dt2 contains rows and 70 columns.
and 10 columns of dt1 matches with dt2. 30 rows of dt1 matches with dt2.
so I want to compare the primary key of both datatable and after if they match the update column values from dt1 to dt2.
Here is your answer, consider dt1=Customer and dt2=Order, CustomerId exist in both datatables, and i also joined them using LINQ extension method, and finally select columns from both datatables. Thanks.
static void Main(string[] args)
{
DataTable dt1 = new DataTable(); //dt1=Customer
dt1.Columns.Add("CustomerId", typeof(int));
dt1.Columns.Add("Name", typeof(string));
dt1.Rows.Add(1, "Customer A");
dt1.Rows.Add(2, "Customer B");
dt1.Rows.Add(3, "Customer C");
DataTable dt2 = new DataTable(); //dt2=Order
dt2.Columns.Add("OrderId", typeof(int));
dt2.Columns.Add("CustomerId", typeof(int)); //Fk
dt2.Columns.Add("OrderDate", typeof(DateTime));
dt2.Columns.Add("OrderAmount", typeof(double));
dt2.Rows.Add(1, 1,DateTime.Now,15000);
dt2.Rows.Add(2, 1, DateTime.Now,10000);
dt2.Rows.Add(3, 2, DateTime.Now,25000);
var result = dt2.AsEnumerable()
.Join(dt1.AsEnumerable(),
x => x.Field<int>("CustomerId"), //Order(CustomerId) FK
y => y.Field<int>("CustomerId"), //Customer Id(Pk)
(x, y) => new { dt2 = x, dt1 = y }) //dt2=Order, dt1=Customer
.Select(x => new
{
OrderId = x.dt2.Field<int>("OrderId"),
CustomerId = x.dt1.Field<int>("CustomerId"),
Name = x.dt1.Field<string>("Name"),
OrderDate = x.dt2.Field<DateTime>("OrderDate"),
OrderAmount = x.dt2.Field<double>("OrderAmount"),
});
foreach (var item in result)
{
Console.WriteLine("Order Id: {0}, CustomerId: {1}, Name: {2}, OrderDate: {3}, OrderAmount: {4}",
item.OrderId,item.CustomerId,item.Name,item.OrderDate,item.OrderAmount);
}
Console.ReadKey();
}
You will need to reference the tables individually unfortunately.
UPDATE tbl1 SET
col2c=(SELECT colc2 FROM tbl2 WHERE tbl2_pk=tbl1.tbl1_pk),
col4e=(SELECT cole4 FROM tbl2 WHERE tbl2_pk=tbl1.tbl1_pk)
WHERE test.tbl1.tbl1_pk=(SELECT tbl2_pk FROM tbl2 WHERE tbl1_pk=tbl2_pk)
Link to see results in table pre and post execution

Delete using LINQ by joining two datatables

I have two datatable DurationByCurrency(inside a dataset) and Fund which looks like below
I want to delete the rows in Duration By Currency Datatable whose FundCode has value as 2 in Fund Dt by performing a join.
var result = from table1 in raptorDS.Tables[RaptorTable.DurationByCurrency].AsEnumerable()
join table2 in fundDT.AsEnumerable()
on table1.Field<string>("FundCode") equals table2.Field<string>("FundCode") into ps
from row in ps.DefaultIfEmpty()
{
//delete query
}
Please help me on this as I am new to LINQ.
var result = from row1 in raptorDS.Tables[RaptorTable.DurationByCurrency].AsEnumerable()
join row2 in fundDT.AsEnumerable()
on row1.Field<string>("FundCode") equals row2.Field<string>("FundCode")
where row1.Field<string>("value")
equals "2" select row1;
result.ToList().ForEach(row => row.Delete());
sample test code for linqpad:
void Main()
{
//sample data for test
DataSet ds = new DataSet();
ds.Tables.Add(GetTable1());
ds.Tables.Add(GetTable2());
var result = ( from rec1 in ds.Tables[0].AsEnumerable()
join rec2 in ds.Tables[1].AsEnumerable()
on rec1.Field<string>("FC") equals rec2.Field<string>("FC")
where rec2.Field<int>("Value") == 2 select rec1);
result.ToList().ForEach(row => row.Delete());
//now you have only "ABCD" and "AZY" in table 1
//ds.Tables[0].Dump(); linqpad display result
}
DataTable GetTable1()
{
DataTable table = new DataTable();
table.Columns.Add("FC", typeof(string));
table.Rows.Add("ABCD");
table.Rows.Add("XYZ");
table.Rows.Add("AZY");
return table;
}
DataTable GetTable2()
{
DataTable table = new DataTable();
table.Columns.Add("FC", typeof(string));
table.Columns.Add("Value", typeof(int));
table.Rows.Add("ABCD", 1);
table.Rows.Add("XYZ", 2);
table.Rows.Add("AZY",3);
return table;
}

How to compare two DataTables with common values

I have two datatable dt1 and st2.
dt1 consists of PorductId ProductName FilePath:
1 Product1 c:\
2 Product2 c:\
3 Product3 c:\
4 Product4 c:\
dt2 consists of ProductName DateofDelivery:
Product2 2016-01-03
Product3 2016-03-02
Product5 2016-02-03
Product7 2014-09-01
I need to return all rows from dt2 where the ProductName of dt2 is in dt1 the result should be:
Product2 2016-01-03
Product3 2016-03-02
I've tried this, but its not working:
var matched = from table1 in dt1.AsEnumerable()
join table2 in dt2.AsEnumerable()
on table1.Field<string>("ProductName") equals table2.Field<string>("ProductName")
Really what you want to do is filter the second Datatable by the first, I would use a where instead of a join, the example below should replicate what your trying to do:
//Assemble the DataTables mentioned in your question
DataTable dt1 = new DataTable();
dt1.Columns.Add("ID", typeof(int));
dt1.Columns.Add("ProductName", typeof(string));
dt1.Columns.Add("Path", typeof(string));
dt1.Rows.Add(1, "Product1", "c:\\");
dt1.Rows.Add(2, "Product2", "c:\\");
dt1.Rows.Add(3, "Product3", "c:\\");
dt1.Rows.Add(4, "Product4", "c:\\");
DataTable dt2 = new DataTable();
dt2.Columns.Add("ProductName", typeof(string));
dt2.Columns.Add("Date", typeof(string));
dt2.Rows.Add("Product2", "2016-01-03");
dt2.Rows.Add("Product3", "2016-01-04");
dt2.Rows.Add("Product5", "2016-01-05");
dt2.Rows.Add("Product7", "2016-01-06");
//Get the values from dt1 to filter by
var filter = dt1.AsEnumerable().Select(b => b.Field<string>("ProductName")).ToList();
//Then filter the second list by the ProductName of the first list
var matched = dt2.AsEnumerable().Where(a => filter.Contains(a.Field<string>("ProductName")))
.ToList();
Hope that helps
try test this code
var dtproducts = dt1.Rows.Select(x => [ProductName]).ToArray();
var matches = (from System.Data.DataRow product in st1.Rows
where dtproducts.Contains(product["ProductName"])
select product).ToList();

compare two datatables with multiple columns with a unique id

I have written a program to compare two datatables with unique ids and create another datatable to insert certain columns which have the same id in common. I have demonstrated my requirement below.
These are the tables that needs to be compared:
And i need the output as below
but i receive an empty table as the result. I cannot understand where have i gone wrong. Could you please help me on this. I have provided my coding below.Please not that quantity and input are two datatables
DataTable result = new DataTable();
result.Columns.AddRange(new DataColumn[2] { new DataColumn("id"), new DataColumn("qty") });
foreach (DataRow row1 in input.Rows)
{
foreach (DataRow row2 in quantity.Rows)
{
if (row1["id"].ToString() == row2["id"].ToString())
{
result.ImportRow(row2);
}
else
{
result.ImportRow(row1);
}
}
}
return result;
You need a Left Join of 2 Data tables.
DataTable dtinput = new DataTable();
DataTable dtquantity = new DataTable();
dtinput.Columns.Add("id",typeof(int));
dtinput.Rows.Add("2");
dtinput.Rows.Add("4");
dtinput.Rows.Add("7");
dtquantity.Columns.Add("id", typeof(int));
dtquantity.Columns.Add("qty", typeof(int));
dtquantity.Rows.Add("1", "12");
dtquantity.Rows.Add("2", "13");
dtquantity.Rows.Add("3", "5");
dtquantity.Rows.Add("4", "6");
dtquantity.Rows.Add("7", null);
var results = from table1 in dtinput.AsEnumerable()
join table2 in dtquantity.AsEnumerable()
on (int)table1["id"] equals (int)table2["id"]
into outer
from row in outer.DefaultIfEmpty<DataRow>()
select row;
DataTable dt = results.CopyToDataTable();
This diagram should help you in future:
Try something like this:
var result = input.Rows.Where(x => quantity.Rows.Amy(y => x == y));
I hope this helps!

Converting anonymous type to DataTable

What is the fastest way to convert anonymous type to DataTable?
Update:
I want to get and populate DataTable from anonymous type. If reflection is neccesary, how can I to do it using reflection?
Found here:
var result = from p in dataSource
group p by p.City into cities
select new { Property1 = cities.Key, Property 2= cities.Average(p => p.Age) };
dt.Columns.Add("Property1");
dt.Columns.Add("Property2");
foreach (var item in result)
{
dt.Rows.Add(item.Property1,item.Property2);
}
See here for a generic solution: Convert generic List/Enumerable to DataTable?
///fill dt1
Dim dt1 As New DataTable dt1 = connection.LoadPoliceData("")
///fll dt2
Dim dt2 As New DataTable dt2 = connection.LoadDataCompare("")
////fill enumerable data(anonymous data) in dt , using linq query
Dim dt As New DataTable
dt.Columns.Add("Name", GetType(String))
dt.Columns.Add("Mobile", GetType(String))
Dim data1 = (From datarow1 In dt1.AsEnumerable Join datarow2 In dt2.AsEnumerable
On datarow1.Field(Of String)("NameofPerson") Equals datarow2.Field(Of String)("Name") And datarow1.Field(Of String)("Mobile") Equals datarow2.Field(Of String)("MobileNumber")
Select dt.LoadDataRow(New Object() {datarow1.Field(Of String)("NameofPerson"), datarow2.Field(Of String)("MobileNumber")}, False)).Distinct().ToList()
Dim i = dt.Rows.Count
record in dt(datatable variable )
///summary fill datatable one (dt1)
Dim dt1 As New DataTable
dt1 = connection.LoadPoliceData("")
///summary fill datatable one (dt2)
Dim dt2 As New DataTable
dt2 = connection.LoadDataCompare("")
/// summary declare datatable save . where i want fill Enumerable data
Dim save As New DataTable
save.Columns.Add("Name", GetType(String))
save.Columns.Add("Mobile", GetType(String))
///summary writing linq query with join of dt1 and dt2 , And datatable(save)
Dim data1 = (From datarow1 In dt1.AsEnumerable
Join datarow2 In dt2.AsEnumerable
On datarow1.Field(Of String)("NameofPerson") Equals datarow2.Field(Of String)("Name") And datarow1.Field(Of String)("Mobile") Equals datarow2.Field(Of String)("MobileNumber")
Select save.LoadDataRow(New Object() {datarow1.Field(Of String)("NameofPerson"), datarow2.Field(Of String)("MobileNumber")}, False)).Distinct().ToList()
///summary count of datatable save
Dim i = save.Rows.Count

Categories

Resources