2012-10-18 24 views
0

我想内部联接2使用Linq的DataColumns上的DataTables,我可以得到使用Linq的行如何我无法获得列。我已经评论了我试图做的如何获取列,如下所示。获取一个内部联接的列LINQ查询

这样做的原因。

我正在计划制作3种方法,LEFT JOIN,FULL JOIN和INNER JOIN,它们将返回一个DataTable,我试图使它尽可能通用,如果下面是一个好方法,不,我需要做到尽可能优化。

 public static DataTable InnerJoin 
    (DataTable dt1, DataTable dt2,DataColumn Parent,DataColumn Child) 
    { 
      DataTable result = new DataTable(); 


      var query = 
       from d in dt1.AsEnumerable() 
       join c in dt2.AsEnumerable() on d[Parent] equals c[Child] 
       select new { d, c }; 
     /* 
     var columns = from d in dt1.Columns.Cast<DataColumn>() 
         from c in dt2.Columns.Cast<DataColumn>() 
          select new{c,d} 
      foreach (var column in columns) 
      { 
       result.Columns.Add(column); 
      } 
      **/ 

      foreach (var row in query) 
      { 
       result.Rows.Add(row); 
      } 

     return result; 
    } 
+1

[codereview.stackexchange.com(http://www.codereview.stackexchange.com)。 –

+1

由于row是不可以[添加到RowCollection](http://msdn.microsoft.com/en-us/library/9yfsd47w.aspx)的不可数类型,因此无法编译。编辑:它编译,因为有一个重载,它需要一个params对象[]。但是,您需要添加两个类型为“DataRow”的列。 –

+1

yeah.rows是在anonumous类型。 – TechGuy

回答

1

你的代码编译,因为有一个overload这需要一个params object[]。但是,您需要添加两个类型为DataRow的列。

public static DataTable InnerJoin(DataTable dt1, DataTable dt2, DataColumn Parent, DataColumn Child) 
{ 
    DataTable result = new DataTable(); 
    result.Columns.Add("Row1", typeof(DataRow)); 
    result.Columns.Add("Row2", typeof(DataRow)); 

    var query = 
     from row1 in dt1.AsEnumerable() 
     join row2 in dt2.AsEnumerable() on row1[Parent] equals row2[Child] 
     select new { row1, row2 }; 

    foreach (var x in query) 
    { 
     result.Rows.Add(x.row1, x.row2); 
    } 

    return result; 
} 

如果这就是你所需要的,它应该工作。

编辑:和这里的(工作)测试

DataTable table1 = new DataTable("table1"); 
table1.Columns.Add("ID", typeof(int)); 
table1.Columns.Add("Name", typeof(String)); 

object[] a1 = { 1, "T1Row1Name" }; 
object[] a2 = { 2, "T1Row2Name" }; 
object[] a3 = { 3, "T1Row3Name" }; 
object[] a4 = { 4, "T1Row4Name" }; 
table1.Rows.Add(a1); 
table1.Rows.Add(a2); 
table1.Rows.Add(a3); 
table1.Rows.Add(a4); 

DataTable table2 = new DataTable("table2"); 
table2.Columns.Add("ID", typeof(int)); 
table2.Columns.Add("Name", typeof(String)); 
table2.Columns.Add("Table1ID", typeof(int)); 


object[] b1 = { 1, "T2Row1Name", 1 }; 
object[] b2 = { 2, "T2Row2Name", 2 }; 
object[] b3 = { 3, "T2Row3Name", 2 }; 
object[] b4 = { 4, "T2Row4Name", 2 }; 
object[] b5 = { 5, "T2Row5Name", 3 }; 
table2.Rows.Add(b1); 
table2.Rows.Add(b2); 
table2.Rows.Add(b3); 
table2.Rows.Add(b4); 
table2.Rows.Add(b5); 

var joinedTable = InnerJoin(table1, table2, table1.Columns["ID"], table2.Columns["Table1ID"]); 

foreach (DataRow r in joinedTable.Rows) 
{ 
    DataRow r1 = r.Field<DataRow>("Row1"); 
    DataRow r2 = r.Field<DataRow>("Row2"); 
    String r1Name = r1.Field<String>("Name"); 
    String r2Name = r2.Field<String>("Name"); 
} 
+0

@ Dreamer78692:也许你想将自定义类的返回值封装在继承'DataTable'或_has_'DataTable'的自定义类中,例如'JoinedTable'你可以扩展来启用多个表。然后你可以让代码更具可读性。 –