簡體   English   中英

將數據表復制為另一個數據表中的列

[英]Copy datatable as columns in another datatable

我有幾個DataTable,我需要將它們復制到另一個DataTable中。 例如,正如您在附圖中看到的那樣,我需要從源表1中獲取所有數據並將其復制到Dest Table的前2列中,在接下來的2列中復制Source Table 2,依此類推。 如何輕松實現這一目標?

在此輸入圖像描述

編輯:我必須閱讀幾個excel文件(我將每個文件存儲在數據表中),我不知道我將擁有多少源表,因此必須以某種方式動態完成。

假設您的源表具有相同的結構,您可以使用Table.Copy()創建dest表,然后在循環中復制數據:

List<DataTable> sourceTables = getYourSourceTablesMethod();
if (sourceTables.Length>0)
{
    DataTable destTable = sourceTables[0].Copy();  

    for (int i = 1; i < sourceTables; i++) 
    {
       foreach (DataRow drow in sourceTables[i].Rows) 
       destTable.Rows.Add(drow.ItemArray);
    }
}

您可以使用框架提供的Merge方法,用於使用和額外信息,請參閱Microsoft Datatable Merge

您應該找到該源表之間的關系。 例如,它們具有相同的ID,您可以像這樣復制它們

insert into destTable( 
select s1.col1, s1.col2, s2.col3, s2.col4, s3.col5, s3.col6, s4.col7, s4.col8 
from sourcetable1 s1, sourcetable2 s2, sourcetable3 s3, sourcetable4 s4 
where s1.id = s2.id and s2.id = s3.id and s3.id = s4.id) 

您可以觸發以下查詢:

select col1,col2 into sourcetable1 from destTable
union
select col3,col4 into sourcetable2 from destTable
union
select col5,col6 into sourcetable3 from destTable
union
select col7,col8 into sourcetable4 from destTable

或者,可以按照這里提到的技術。

在數據行的情況下,它可以是:

foreach (DataRow row in DestTable)
{
    SourceTable1.ImportRow(row);
}

您可以先創建目標表,添加它的列(通過匯總所有輸入表中的列數),然后通過連接輸入表中每行的各個值數組來添加它的行。

當然,結果DataTable行將包含每個輸入表在頂部向下方向顯示的值(在頂部對齊)。 它還意味着結果行的數量是最大輸入表中的行數。

首先,我們將初始化並填充List<DataTable>變量,然后我們將使用此變量作為方法參數執行連接:

#region table collection initialization
List<DataTable> dts = new List<DataTable>();
var dt = new DataTable();
dt.Columns.Add("Test0", typeof(string));
dt.Rows.Add(1);
dt.Rows.Add(2);
dts.Add(dt);

dt = new DataTable();
dt.Columns.Add("Test1", typeof(int));
dt.Rows.Add(2);
dts.Add(dt);

dt = new DataTable();
dt.Columns.Add("Test3", typeof(int));
dt.Columns.Add("Test4");
dt.Columns.Add("Test5", typeof(int));
dt.Rows.Add(3, "a", 1);
dt.Rows.Add(4);
dt.Rows.Add(5, "a");
dt.Rows.Add(null, "a");
dts.Add(dt);

dt = new DataTable();
dt.Columns.Add("Test6", typeof(DateTime));
dt.Columns.Add("Test7", typeof(int));
dt.Rows.Add(DateTime.Now);
dts.Add(dt);
#endregion

// sample method usage
var result = GetJoinedTable(dts);

讓我們創建GetJoinedTable方法,該方法將result連接表返回到result變量中:

private DataTable GetJoinedTable(List<DataTable> dts)
{
    var dest = new DataTable();

    //will be used if you have non-unique column names
    int counter = 0;

    foreach (var column in dts
        .SelectMany<DataTable, DataColumn>(t =>
            t.Columns.Cast<DataColumn>()))
    {
        dest.Columns.Add(column.ColumnName, column.DataType);

        // if you have non-unique column names use the following instead
        //dest.Columns.Add(String.Format("column_{0}", counter++), 
        //    column.DataType);
    }

    List<object> rowItems;

    for (int i = 0; i < dts.Max(t => t.Rows.Count); i++)
    {
        rowItems = new List<object>();
        for (int j = 0; j < dts.Count; j++)
        {
            if (dts[j].Rows.Count > i)
            {
                var r = dts[j].Rows[i].ItemArray
                    .Select((v, index) =>
                        (v == null || v == System.DBNull.Value)
                            ? GetDefault(dts[j].Columns[index].DataType) : v);
                rowItems.AddRange(r);
            }
            else
            {
                for (int c = 0; c < dts[j].Columns.Count; c++)
                {
                    rowItems.Add(GetDefault(dts[j].Columns[c].DataType));
                }
            }
        }
        dest.Rows.Add(rowItems.ToArray());
    }

    return dest;
}

您還需要添加以下方法,該方法根據列的DataType屬性返回相應的默認列值:

object GetDefault(Type t)
{
    if (t.IsValueType)
    {
        return Activator.CreateInstance(t);
    }
    else
    {
        return null;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM