How to compare two DataTables with common values - c#

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();

Related

Merge two datatables?

I want to merge two data table in which column "ID" as primary key in both table.
Note: Both table has two column as "ID, Name" & "ID, name" where Name & name is case sensitive.
Table: 1
Table: 2
Expected Merged Table Result:
Code:
public MainWindow()
{
InitializeComponent();
// Table 1
DataTable table1 = new DataTable();
table1.Columns.Add("ID", typeof(int));
table1.Columns.Add("Name", typeof(String));
table1.PrimaryKey = new DataColumn[] { table1.Columns["ID"] };
table1.Rows.Add(1, "A");
table1.Rows.Add(4, "D");
table1.Rows.Add(5, "E");
// Table 2
DataTable table2 = new DataTable();
table2.Columns.Add("ID", typeof(int));
table2.Columns.Add("name", typeof(String));
table2.PrimaryKey = new DataColumn[] { table2.Columns["ID"] };
table2.Rows.Add(1, "A");
table2.Rows.Add(2, "B");
table2.Rows.Add(3, "C");
table2.Rows.Add(5, "E");
table1.Merge(table2);
}
Please help me to achieve this expected result.
You could temporarily change the name of the second column and still use Merge:
const string OriginalName = "name";
const string TemporaryName = "temp";
table2.Columns[OriginalName].ColumnName = TemporaryName;
table1.Merge(table2);
table1.Columns[TemporaryName].ColumnName = OriginalName;
table2.Columns[TemporaryName].ColumnName = OriginalName;
Use this:
DataTable dtResult = new DataTable();
dtResult.Columns.Add("ID", typeof(int));
dtResult.Columns.Add("Name", typeof(string));
dtResult.Columns.Add("name", typeof(string));
var result = from dataRows1 in table1.AsEnumerable()
join dataRows2 in table2.AsEnumerable()
on dataRows1.Field<int>("ID") equals dataRows2.Field<int>("ID")
into rows
from row in rows.DefaultIfEmpty()
select dtResult.LoadDataRow(new object[]
{
dataRows1.Field<int>("ID"),
dataRows1.Field<string>("Name"),
dataRows2.Field<string>("name")
}, false);

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;
}

C# Filter DataTable with multiple keys (columns) and multiple values

I have a table with three columns A, B and C, where A, B are the keys and C is the corresponding value.
I've trying to filter it with multiple values for the keys. In order to do that, I've tried:
// Initialise some data
DataTable dt = new DataTable();
dt.Columns.Add("A", typeof(int));
dt.Columns.Add("B", typeof(int));
dt.Columns.Add("C", typeof(string));
dt.Rows.Add(1, 1, "temp1");
dt.Rows.Add(1, 2, "temp2");
dt.Rows.Add(2, 1, "temp3");
dt.Rows.Add(2, 2, "temp4");
dgv1.DataSource = dt;
// Filter the DataTable to show the second and third lines of `dt`
DataView dv = new DataView(dt);
dv.RowFilter = "(A = 1 and B = 2) and (A = 2 and B = 1)";
dgv2.DataSource = dv;
After the RowFilter, the dv is empty. But I was expecting to receive the second and third lines from the DataTable.
If I do:
dv.RowFilter = "(A = 1 and B = 2)";
it filters fine, but it shows just one line (not what I really need).
Does anyone know how to filter a DataTable with multiple values and multiple keys?
Thanks!
If I understand correctly, you can use dv.RowFilter = "((A = 1 and B = 2) or (A = 2 and B = 1))"
The reason your original filter was not giving you any results, is because A can't = 1 AND 2, likewise with B. What you are looking for is one OR the other.

merge 2 datatable

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")
}
);

Categories

Resources