7

この質問と同様の方法で、2つのDataTableを結合しようとしています。

C#でのDataTablesの内部結合

出力を、元の両方のテーブルの列を含む単一の「結合された」テーブルにしようとしています。どちらにも共通の日付スタンプ列があります。

与えられた答えは、固定列を持つDataTableに適していますが、動的に作成され、任意の数の列を持つことができる場合、どうすればそれらを結合できますか?

例えば

T1 (datestamp, t1Column1, t1Column2, t1ColumnN...)
T2 (datestamp, t2Column1, t2Column2, t2ColumnN...)

参加して以下を作成したいと思います。

J1 (datestamp, t1Column1, t1Column2, t1ColumnN, ..., t2Column1, t2Column2, t2ColumnN...)

これは可能ですか?

4

3 に答える 3

9

列のループに依存しない解決策を見つけました。

これは、両方のテーブルに同じ構造が必要だと思ったために以前に却下した「マージ」メソッドを使用します。

まず、2つのデータテーブルに主キーを作成する必要があります。

// set primary key
T1.PrimaryKey = new DataColumn[] { T1.Columns["DateStamp"] };
T2.PrimaryKey = new DataColumn[] { T2.Columns["DateStamp"] };

次に、両方のテーブルをデータセットに追加して、関係を追加できるようにします。

// add both data-tables to data-set
DataSet dsContainer = new DataSet();
dsContainer.Tables.Add(T1);
dsContainer.Tables.Add(T2);

次に、データセットの2つのキー列間の関係を追加します。

// add a relationship between the two timestamp columns
DataRelation relDateStamp = new DataRelation("Date", new DataColumn[] { T1.Columns["DateStamp"] }, new DataColumn[] { T2.Columns["DateStamp"] });
dsContainer.Relations.Add(relDateStamp);

最後に、最初のデータテーブルを新しい「結合された」バージョンにコピーしてから、2番目のデータテーブルにマージできます。

// populate combined data
DataTable dtCombined = new DataTable();
dtCombined = T1.Copy();
dtCombined.Merge(T2, false, MissingSchemaAction.Add);

注:Mergeメソッドでは、2番目の引数がfalseである必要があります。そうでない場合、構造はコピーされますが、2番目のテーブルのデータはコピーされません。

これにより、次のテーブルが結合されます。

T1 (2012-05-09, 111, 222)
T2 (2012-05-09, 333, 444, 555)

主キーに基づいて結合されたバージョンに:

J1 (2012-05-09, 111, 222, 333, 444, 555)
于 2012-05-09T11:54:50.390 に答える
1

リンクされた質問の回答を、列名ではなく列のインデックスを使用するように調整できると思います。または、次のように、各行のアイテムをループすることもできます。

foreach(DataRow row in table.Rows)
{
    foreach(DataColumn column in table.Columns)
    {
        object value = row[column]; // add this to your combined table
    }
}
于 2012-05-08T16:34:43.257 に答える
1

SQLを確実にエミュレートしないこれらすべての内部結合関数を見るのに飽きた後、私はここで自分自身を作成することにしました。

private DataTable JoinDataTables(DataTable t1, DataTable t2, params Func<DataRow, DataRow, bool>[] joinOn)
{
    DataTable result = new DataTable();
    foreach (DataColumn col in t1.Columns)
    {
        if (result.Columns[col.ColumnName] == null)
            result.Columns.Add(col.ColumnName, col.DataType);
    }
    foreach (DataColumn col in t2.Columns)
    {
        if (result.Columns[col.ColumnName] == null)
            result.Columns.Add(col.ColumnName, col.DataType);
    }
    foreach (DataRow row1 in t1.Rows)
    {
        var joinRows = t2.AsEnumerable().Where(row2 =>
            {
                foreach (var parameter in joinOn)
                {
                    if (!parameter(row1, row2)) return false;
                }
                return true;
            });
        foreach (DataRow fromRow in joinRows)
        {
            DataRow insertRow = result.NewRow();
            foreach (DataColumn col1 in t1.Columns)
            {
                insertRow[col1.ColumnName] = row1[col1.ColumnName];
            }
            foreach (DataColumn col2 in t2.Columns)
            {
                insertRow[col2.ColumnName] = fromRow[col2.ColumnName];
            }
            result.Rows.Add(insertRow);
        }
    }
    return result;
}

これを使用する方法の例:

var test = JoinDataTables(transactionInfo, transactionItems,
               (row1, row2) =>
               row1.Field<int>("TransactionID") == row2.Field<int>("TransactionID"));
于 2012-07-16T13:26:55.643 に答える