6

いくつかの DataTable があり、それらを別の DataTable にコピーする必要があります。たとえば、添付の図でわかるように、ソース テーブル 1 からすべてのデータを取得し、それを宛先テーブルの最初の 2 列にコピーし、ソース テーブル 2 を次の 2 列にコピーする必要があります。 . どうすればこれを簡単に達成できますか?

ここに画像の説明を入力

編集:いくつかのExcelファイルを読み取る必要があり(各ファイルをデータテーブルに保存しています)、ソーステーブルの数が正確にわからないため、これは何らかの方法で動的に行う必要があります.

4

5 に答える 5

1

フレームワークによって提供される Merge メソッドを使用できます。使用方法と追加情報については、Microsoft Datatable Mergeを参照してください。

于 2013-06-04T07:38:30.257 に答える
1

そのソース テーブル間の関係を見つける必要があります。たとえば、同じ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) 
于 2013-06-04T07:39:40.967 に答える
0

最初に宛先テーブルを作成し、(すべての入力テーブルの列数を合計して) 列を追加し、次に入力テーブルの各行の値の個々の配列を連結して行を追加します。

もちろん、結果の行には、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

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;
    }
}
于 2013-06-04T07:44:01.650 に答える