23

両方のテーブルのすべての列を保持しながら、次のテーブルと条件で 2 つのデータ テーブルを左外部結合するにはどうすればよいですか?

dtbl左:

 id   col1   anotherColumn2
 1    1      any2
 2    1      any2
 3    2      any2
 4    3      any2
 5    3      any2
 6    3      any2
 7           any2

dtbl右:

 col1   col2      anotherColumn1
 1      Hi        any1
 2      Bye       any1
 3      Later     any1
 4      Never     any1

dtbl参加:

 id   col1  col2     anotherColumn1     anotherColumn2
 1    1     Hi       any1               any2
 2    1     Hi       any1               any2
 3    2     Bye      any1               any2
 4    3     Later    any1               any2
 5    3     Later    any1               any2
 6    3     Later    any1               any2
 7                                      any2

条件:

  • dtblLeft では、col1 が一意の値を持つ必要はありません。
  • dtblRight では、col1 に固有の値があります。
  • dtblLeft の col1 に外部キーがない場合、または dtblRight に存在しない外部キーがある場合は、空または null フィールドが挿入されます。
  • col1 に参加しています。

通常の DataTable 操作、LINQ などを使用できます。

私はこれを試しましたが、重複を削除します:

dtblA.PrimaryKey = new DataColumn[] {dtblA.Columns["col1"]}

DataTable dtblJoined = new DataTable();
dtblJoined.Merge(dtblA, false, MissingSchemaAction.AddWithKey);
dtblJoined.Merge(dtblB, false, MissingSchemaAction.AddWithKey);

編集1:

これは私が望むものに近いですが、テーブルの1つからの列しかありません(このリンクにあります):

    dtblJoined = (from t1 in dtblA.Rows.Cast<DataRow>()
                  join t2 in dtblB.Rows.Cast<DataRow>() on t1["col1"] equals t2["col1"]
                  select t1).CopyToDataTable();

編集2:

このリンクからの回答は私にとってはうまくいくようですが、次のように少し変更する必要がありました。

DataTable targetTable = dtblA.Clone();
var dt2Columns = dtblB.Columns.OfType<DataColumn>().Select(dc =>
new DataColumn(dc.ColumnName, dc.DataType, dc.Expression, dc.ColumnMapping));
var dt2FinalColumns = from dc in dt2Columns.AsEnumerable()
                   where targetTable.Columns.Contains(dc.ColumnName) == false
                   select dc;

targetTable.Columns.AddRange(dt2FinalColumns.ToArray());

var rowData = from row1 in dtblA.AsEnumerable()
                          join row2 in dtblB.AsEnumerable()
                          on row1["col1"] equals row2["col1"]
                          select row1.ItemArray.Concat(row2.ItemArray.Where(r2 => row1.ItemArray.Contains(r2) == false)).ToArray();

 foreach (object[] values in rowData)
      targetTable.Rows.Add(values);

私もこのリンクを見つけました。より簡潔に見えるので、それを試してみるかもしれません。

編集 3 (2013 年 11 月 18 日):

より多くの状況を反映するように表を更新しました。

4

3 に答える 3