2016-07-27 58 views
1

我在寫一個連接不同數據庫系統的c#應用程序。這些系統可以是平面文件數據庫,Oracle,Sql,Excel文件,分機。 C#應用程序的工作是提供一個可以在一個位置使所有這些源可用的途徑。所以基本上,應用程序接受各個數據庫系統的查詢和連接設置列表,並收集一堆結果。有沒有一種簡單的方法,在C#中的INNER連接,外部連接,左外部連接,右外部連接或UNION兩個(或更多)DataTables?

目標是輸出單個DataTable,並將所有這些查詢的結果一起加入/組合在一起(取決於設置)。 C#提供了一種簡單的方法來在DataTable列表上執行任何聯合/聯合操作嗎?

例如:

Table1: 
__________________________________________________________ 
|tb1_pk_id| tb1_name | tb1_data1 | tb1_data2 | 
|---------|---------------|---------------|---------------| 
| 1 | tb1name_blah1 | tb1dat1_blah1 | tb1dat2blah1 | 
| 2 | tb1name_blah2 | tb1dat1_blah2 | tb1dat2blah2 | 
| 3 | tb1name_blah3 | tb1dat1_blah3 | tb1dat2blah3 | 
----------------------------------------------------------- 

Table2: 
__________________________________________________________ 
|tb2_pk_id| tb2_name | tb2_data1 | tb2_data2 | 
|---------|---------------|---------------|---------------| 
| 1 | tb2name_blah1 | tb2dat1_blah1 | tb2dat2blah1 | 
| 2 | tb2name_blah2 | tb2dat1_blah2 | tb2dat2blah2 | 
| 3 | tb2name_blah3 | tb2dat1_blah3 | tb2dat2blah3 | 
----------------------------------------------------------- 

Join Results: 
__________________________________________________________ _______________________________________________ 
|tb1_pk_id| tb1_name | tb1_data1 | tb1_data2 | tb2_name | tb2_data1 | tb2_data2 | 
|---------|---------------|---------------|---------------|---------------|---------------|---------------| 
| 1 | tb1name_blah1 | tb1dat1_blah1 | tb1dat2blah1 | tb2name_blah1 | tb2dat1_blah1 | tb2dat2blah1 | 
| 2 | tb1name_blah2 | tb1dat1_blah2 | tb1dat2blah2 | tb2name_blah2 | tb2dat1_blah2 | tb2dat2blah2 | 
| 3 | tb1name_blah3 | tb1dat1_blah3 | tb1dat2blah3 | tb2name_blah3 | tb2dat1_blah3 | tb2dat2blah3 | 
----------------------------------------------------------------------------------------------------------- 

到目前爲止,我已經找到了下面的代碼在線(here)做一個合併上的所有數據:

private DataTable MergeAll(IList<DataTable> tables, String primaryKeyColumn) 
     { 
      if (!tables.Any()) 
       throw new ArgumentException("Tables must not be empty", "tables"); 
      if (primaryKeyColumn != null) 
       foreach (DataTable t in tables) 
        if (!t.Columns.Contains(primaryKeyColumn)) 
         throw new ArgumentException("All tables must have the specified primarykey column " + primaryKeyColumn, "primaryKeyColumn"); 

      if (tables.Count == 1) 
       return tables[0]; 

      DataTable table = new DataTable("TblUnion"); 
      table.BeginLoadData(); // Turns off notifications, index maintenance, and constraints while loading data 
      foreach (DataTable t in tables) 
      { 
       table.Merge(t); // same as table.Merge(t, false, MissingSchemaAction.Add); 
      } 
      table.EndLoadData(); 

      if (primaryKeyColumn != null) 
      { 
       // since we might have no real primary keys defined, the rows now might have repeating fields 
       // so now we're going to "join" these rows ... 
       var pkGroups = table.AsEnumerable() 
        .GroupBy(r => r[primaryKeyColumn]); 
       var dupGroups = pkGroups.Where(g => g.Count() > 1); 
       foreach (var grpDup in dupGroups) 
       { 
        // use first row and modify it 
        DataRow firstRow = grpDup.First(); 
        foreach (DataColumn c in table.Columns) 
        { 
         if (firstRow.IsNull(c)) 
         { 
          DataRow firstNotNullRow = grpDup.Skip(1).FirstOrDefault(r => !r.IsNull(c)); 
          if (firstNotNullRow != null) 
           firstRow[c] = firstNotNullRow[c]; 
         } 
        } 
        // remove all but first row 
        var rowsToRemove = grpDup.Skip(1); 
        foreach (DataRow rowToRemove in rowsToRemove) 
         table.Rows.Remove(rowToRemove); 
       } 
      } 

      return table; 
     } 

這工作得很好做工會,但我不知道是否有一種更簡單的方法來做到這一點已經存在於.NET中,讓我做任何種類的聯合或聯合在一組分離數據表(不只是聯合在t他上面的代碼)還是我必須自定義代碼的每種類型的聯合/聯合?

回答

2

沒有,沒有這樣做的一個簡單的.NET方法....

LINQ可以接近......你可以創建表格LINQ加入,但它們通常是「內連接」。做一個「左連接」有點複雜,需要GroupJoin關鍵字。 https://msdn.microsoft.com/en-us/library/bb386969(v=vs.110).aspx

如果您想「自己動手」與ADO.Net DataRelations,可能這個老VB.Net文章在一起來看看:

http://www.emmet-gray.com/Articles/DataRelations.html

+0

我有一種感覺,這是案件,我只是想確保我沒有失去一些東西。我會研究使用LINQ方法。謝謝! –