2016-10-27 14 views
1

2つの同様のデータグリッドを保持するwinformに取り組んでいます。それぞれのデータソースは同じテーブルの別のインスタンスに設定されています。テスト目的のために、テーブルは異なるレコードと類似したレコードの両方を持ち、それぞれのレコードに異なるセルが入っています。データマージとリジェクトが意図した通りに動作しない

1 - Datatable.Mergeを呼び出すと、ターゲットテーブルに不足している行が取得されますが、最初の行には空のセルがソーステーブルの対応するセルから更新されません。

2ターゲットテーブルでDatatable.RejectChangesを呼び出すと、マージによって追加された行は削除されませんが、今回は最初の行の空のセルが問題のセルの対応するセルから正しく更新されます。私がマージするときに起こると思うソーステーブル。

テーブルを埋めるために使用される機能:

private bool OpenFile(Datatable table) 
{ 
    if (OFD.ShowDialog() == DialogResult.OK) // OFD is OpenFileDialog 
    { 
     if (UserPrompt.ShowDialog() == DialogResult.OK) // UserPrompt is a custom input dialog for user credentials 
     { 
      try 
      { 
       // code to fill table not shown for readability, works well anyway 
       table.AcceptChanges(); // otherwise all the records are deleted after RejectChanges, including the initial ones       
       return true; 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message, "Operation Canceled", MessageBoxButtons.OK, MessageBoxIcon.Error); 
      } 
     } 
    } 

    return false; 
} 

マージ機能:

private void menuMerge1_Click(object sender, EventArgs e) 
{ 
    Table1.Merge(Table2, true); 
    if (MessageBox.Show("Table 2 merged to table 1. Save changes? Choosing no will cancel the merging.", "Keep or Discard Changes", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.OK) 
     Save(Table1); // saving to file, custom function 
    else Table1.RejectChanges(); 
} 

のOpenFile関数が最初に呼び出されたが、その後、マージは、それはそれです。

私が試してみました:

  • はDataGridViewのをリフレッシュします。
  • DataGridViewのDataSourceをリセットします。
  • マージ後にターゲットのAcceptChangesを呼び出します。

ありがとうございました!

+2

私はより良いアプローチは、最初にユーザーに尋ねてから、他の方法ではなくマージすることです。大きなテーブルの貴重なプロセッサ時間を節約できます。 –

+0

@Abdul Rehman Sayed:True。私はテーブルをマージする信頼できる方法を見つけるとすぐにこれを変更します:) – Frank

答えて

0

まず、DataTable.Mergeはイベントを発生させません。つまり、RejectChangesは変更された行でのみ動作し、追加された行は変更なしとしてマークされます。解決策は、カスタムマージ機能をコーディングすることでした。

private bool Merge(DataTable target, DataTable source, bool preserve) 
    {   
     if (!preserve) 
     { 
      target.Merge(source, false); 
      return true; 
     }    
     else 
     { 
      DataRow drTargetMatch; 
      DataRow drNew; 
      int numCol = source.Columns.Count; 
      int index = 1; 

      try 
      { 
       foreach (DataRow dr in source.Rows) 
       { 
        drTargetMatch = target.Rows.Find(dr[0]); 
        if (drTargetMatch == null) // source row does not exist in target, add a copy 
        { 
         drNew = target.NewRow(); 
         drNew.ItemArray = dr.ItemArray; 
         target.Rows.Add(drNew); 
        } 
        else // source row exists in target, update empty values 
        { 
         for (index = 1; index < numCol; index++) // start at 1 since we don't update PK 
         { 
          if (drTargetMatch.IsNull(index) && !dr.IsNull(index)) 
           drTargetMatch[index] = dr[index];         
         } 
        } 
       } 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message, "Operation Canceled", MessageBoxButtons.OK, MessageBoxIcon.Error); 
       target.RejectChanges(); 
       return false; 
      } 

      return true; 
     }       
    } 
関連する問題