简体   繁体   中英

Is there a way to join 2 data tables on multiple columns through Linq?

I have two data tables.

1st table:

在此处输入图像描述

2nd table:

在此处输入图像描述

I want the following result:

在此处输入图像描述

But I'm getting this result instead:

在此处输入图像描述

Here is my code:

table1.Columns.Add("D");

table1.AsEnumerable()
      .Join(table2.AsEnumerable(),
            dt1_Row => dt1_Row.ItemArray[0],                         
            dt2_Row => dt2_Row.ItemArray[0],
            (dt1_Row, dt2_Row) => new { dt1_Row, dt2_Row})
      .ToList()                         
      .ForEach(o => o.dt1_Row.SetField(3, o.dt2_Row.ItemArray[2]));

Thank you in advance!

Here is answer -

        DataRow dataRow = null;
        DataTable dt1 = new DataTable();
        dt1.Columns.Add("A");
        dt1.Columns.Add("B");
        dt1.Columns.Add("C");
        dataRow = dt1.NewRow();
        dataRow["A"] = "Australia";
        dataRow["B"] = "P1";
        dataRow["C"] = "15";
        dt1.Rows.Add(dataRow);

        dataRow = dt1.NewRow();
        dataRow["A"] = "Australia";
        dataRow["B"] = "P2";
        dataRow["C"] = "4";
        dt1.Rows.Add(dataRow);

        dataRow = dt1.NewRow();
        dataRow["A"] = "Australia";
        dataRow["B"] = "P3";
        dataRow["C"] = "4";
        dt1.Rows.Add(dataRow);

        dataRow = dt1.NewRow();
        dataRow["A"] = "Australia";
        dataRow["B"] = "P4";
        dataRow["C"] = "51";
        dt1.Rows.Add(dataRow);

        dataRow = dt1.NewRow();
        dataRow["A"] = "Australia";
        dataRow["B"] = "P5";
        dataRow["C"] = "4";
        dt1.Rows.Add(dataRow);

        dataRow = dt1.NewRow();
        dataRow["A"] = "Canada";
        dataRow["B"] = "P1";
        dataRow["C"] = "9";
        dt1.Rows.Add(dataRow);

        
        dataRow = dt1.NewRow();
        dataRow["A"] = "Canada";
        dataRow["B"] = "P2";
        dataRow["C"] = "5";
        dt1.Rows.Add(dataRow);

        dataRow = dt1.NewRow();
        dataRow["A"] = "Canada";
        dataRow["B"] = "P3";
        dataRow["C"] = "19";
        dt1.Rows.Add(dataRow);

        dataRow = dt1.NewRow();
        dataRow["A"] = "Canada";
        dataRow["B"] = "P4";
        dataRow["C"] = "79";
        dt1.Rows.Add(dataRow);

        dataRow = dt1.NewRow();
        dataRow["A"] = "Canada";
        dataRow["B"] = "P5";
        dataRow["C"] = "23";
        dt1.Rows.Add(dataRow);

        dt1.AcceptChanges();

        dataRow = null;
        DataTable dt2 = new DataTable();
        dt2.Columns.Add("A");
        dt2.Columns.Add("B");
        dt2.Columns.Add("D");
        dataRow = dt2.NewRow();
        dataRow["A"] = "Australia";
        dataRow["B"] = "P1";
        dataRow["D"] = "2";
        dt2.Rows.Add(dataRow);

        dataRow = dt2.NewRow();
        dataRow["A"] = "Canada";
        dataRow["B"] = "P1";
        dataRow["D"] = "3";
        dt2.Rows.Add(dataRow);

        dt2.AcceptChanges();


        var joinResult = (from p in dt1.AsEnumerable()
                          join t in dt2.AsEnumerable()
                          on new
                          {
                              A = p.Field<String>("A"),
                              B = p.Field<String>("B"),
                          } equals
                           new
                           {
                               A = t.Field<String>("A"),
                               B = t.Field<String>("B"),
                           }
                          into grp1
                          from tb3 in grp1.DefaultIfEmpty()
                          select new
                          {
                              A = p.Field<string>("A"),
                              B = p.Field<string>("B"),
                              C = p.Field<string>("C"),
                              D = tb3 == null ? "0" : tb3.Field<string>("D")

                          });

finally, you can enumerate A,B,C,D fields using foreach loop.

Wouldn't this suffice?

    var r = from t1 in table1
            from t2 in table2.Where(t=> t.A == t1.A && t.B == t1.B).Select(t=>t.D).DefaultIfEmpty()
            select new {t1.A, t1.B, t1.C, t2.D}

I found the below solution:

var list1 = (from t1 in table1.AsEnumerable()
                         select new
                         {
                             A= t1.Field<string>("A"),
                             B = t1.Field<string>("B"),
                             C = t1.Field<int>("C").ToString(),
                             
                         });

            var list2 = (from b in table2.AsEnumerable()
                         select new
                         {
                             A = b.Field<string>("A"),
                             B = b.Field<string>("B"),
                             D = b.Field<int>("D").ToString(),
                             
                         });
            var result = (from x in list1.AsEnumerable()
                          join y in list2.AsEnumerable() on new { x.A, x.B } equals new { y.A, y.B } into xy
                           from y in xy.DefaultIfEmpty()
                          select new { x,xx = y == null ? "0" : y.D  }).ToList();
            

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM