2015-12-12 4 views
0

Я пытаюсь присоединиться к двум типам данных, оба имеют одинаковое количество строк и всего один столбец. Есть ли какой-нибудь причудливый способ в C# для этого? В результате мне нужно datatable с двумя столбцами, где первая строка первого столбца находится рядом с первой строкой второго столбца.C# Присоединиться к двум таблицам данных

+0

Так много ответа на SO: Как: http://stackoverflow.com/questions/20760681/linq-join-two-datatables или HTTP: // stackoverflow.com/questions/285474/merge-2-datatables-and-store-in-a-new-one –

+0

Можете ли вы показать нам, что вы пробовали до сих пор. –

ответ

0

Вот один из способов сделать это, так что в основном он использует перегрузку .Select, который обеспечивает индекс текущего положения в пределах итерации задачи поиска соответствующей строки в table2, что мы в настоящее время, глядя на в table1. Мы создаем массив объектов с двумя элементами из каждой таблицы для каждой строки. Затем мы можем просто использовать LoadDataRow, чтобы поместить их в таблицу назначения с двумя столбцами.

// create a target table with 2 columns 
DataTable destinationTable = new DataTable(); 
destinationTable.Columns.Add("Col1"); 
destinationTable.Columns.Add("Col2"); 

// select all the rows from the first table, combined with the corresponding value for that row in the second table 
var rowsCombined = table1 
    .AsEnumerable() 
    .Select((row, rowNumber) => new object[] { row[0], table2.Rows[rowNumber][0] }); 

foreach (var data in rowsCombined) 
    destinationTable.LoadDataRow(data, true);  
0

С ANSWER по этой ссылке Тима Schmelter ....

public static DataTable MergeAll(this 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; 
} 

Вы можете назвать это таким образом:

var tables = new[] { tblA, tblB, tblC }; 
DataTable TblUnion = tables.MergeAll("c1"); 

С некоторыми данными выборки:

var tblA = new DataTable(); 
tblA.Columns.Add("c1", typeof(int)); 
tblA.Columns.Add("c2", typeof(int)); 
tblA.Columns.Add("c3", typeof(string)); 
tblA.Columns.Add("c4", typeof(char)); 

var tblB = new DataTable(); 
tblB.Columns.Add("c1", typeof(int)); 
tblB.Columns.Add("c5", typeof(int)); 
tblB.Columns.Add("c6", typeof(string)); 
tblB.Columns.Add("c7", typeof(char)); 

var tblC = new DataTable(); 
tblC.Columns.Add("c1", typeof(int)); 
tblC.Columns.Add("c8", typeof(int)); 
tblC.Columns.Add("c9", typeof(string)); 
tblC.Columns.Add("c10", typeof(char)); 

tblA.Rows.Add(1, 8500, "abc", 'A'); 
tblA.Rows.Add(2, 950, "cde", 'B'); 
tblA.Rows.Add(3, 150, "efg", 'C'); 
tblA.Rows.Add(4, 850, "ghi", 'D'); 
tblA.Rows.Add(5, 50, "ijk", 'E'); 

tblB.Rows.Add(1, 7500, "klm", 'F'); 
tblB.Rows.Add(2, 900, "mno", 'G'); 
tblB.Rows.Add(3, 150, "opq", 'H'); 
tblB.Rows.Add(4, 850, "qrs", 'I'); 
tblB.Rows.Add(5, 50, "stu", 'J'); 

tblC.Rows.Add(1, 7500, "uvw", 'K'); 
tblC.Rows.Add(2, 900, "wxy", 'L'); 
tblC.Rows.Add(3, 150, "yza", 'M'); 
tblC.Rows.Add(4, 850, "ABC", 'N'); 
tblC.Rows.Add(5, 50, "CDE", 'O'); 

После того, как запрос mergeAll:

after merge all

Надеется, что это помогает ...

Смежные вопросы