2009-11-02 63 views
0

我最近已經從Java/RMI切換到C#/ .net,並且正在使用數據綁定來更新Oracle中的記錄,這是我的第一個項目。在我建立的第一張表格上,我有車輛記錄的詳細信息(VIN,年/製造/型號,車牌號碼等等)。我以書面形式向DB方面所做的第一件事是節省更新:BindingSource看到的變化,DataTable不

private void btn_saveDesc_Click(object sender, EventArgs e) 
{ 
    bool isSaved = false; 
    hJA_VEHICLEBindingSource.EndEdit(); 
    DataSet1.HJA_VEHICLEDataTable ch = 
     (DataSet1.HJA_VEHICLEDataTable)dataSet1.HJA_VEHICLE.GetChanges(); 
    if (ch == null) 
    { 
     MessageBox.Show("There are no changes to save."); 
    } 
    else 
    { 
     Service<TVDDataService.IService1>.Use(svcProxy => 
      { 
       isSaved = svcProxy.SaveVehicles(ch); 
      }); 
     if (isSaved) 
     { 
      // update the vehicle in the local dataset 
      var modifiedRows = from row in dataSet1.HJA_VEHICLE 
           where row.RowState == DataRowState.Modified 
           select row; 
      foreach (DataRow row in modifiedRows) 
      { 
       row.Delete(); 
      } 
      dataSet1.HJA_VEHICLE.Merge(ch); 
      dataSet1.HJA_VEHICLE.AcceptChanges(); 
     } 
     if(isSaved) 
     { 
      MessageBox.Show("The record has been saved."); 
     } 
     else 
     { 
      MessageBox.Show("The record could not be saved."); 
     } 
    } 
} 

這一切似乎都好了,我轉移到添加新記錄。我做了一個按鈕(我在網上看到那裏各種各樣的人不得不說是一樣好或更好,使自己比使用綁定導航器),並把這個在其處理:

DataRowView drv = (DataRowView)hJA_VEHICLEBindingSource.AddNew(); 
currVeh_id = nextID(); // generate arbitrary ID for the record 
drv["VEH_ID"] = currVeh_id; 
drv["GRNTE_ID"] = lastSelectedGranteeID; // just to have an initial value 
hJA_VEHICLEBindingSource.Filter = "VEH_ID = " + currVeh_id; 

所以有(或以上)我」 m將初始值放入一些必需的列(VEH_ID是PK)。然後我運行應用程序,在VIN的文本框中輸入一個值,然後保存(與上面相同的代碼),這次GetChanges()返回null。

所以,我想這在「新增」按鈕處理程序,在地方的第一件事:

DataSet1.HJA_VEHICLERow newRow = 
    (DataSet1.HJA_VEHICLERow)dataSet1.HJA_VEHICLE.NewRow(); 
currVeh_id = nextID(); 
newRow.VEH_ID = currVeh_id; 
newRow.GRNTE_ID = lastSelectedGranteeID; 
dataSet1.HJA_VEHICLE.AddHJA_VEHICLERow(newRow); 
hJA_VEHICLEBindingSource.Filter = "VEH_ID = " + currVeh_id; 

現在我有一些非常有趣的事情發生。
- 我可以在任何數量的新記錄中成功輸入並保存數據,直到我選擇一個現有記錄。如果我移動到現有記錄然後添加新記錄,那麼當我去保存新記錄時,在代碼中顯式設置的值將被寫入到數據塊中,但輸入到GUI中的數據不會「取」新紀錄。
- 我可以成功更改任何數量的現有記錄,直到輸入新記錄。如果我添加一個或多個新記錄並保存,然後嘗試保存對現有記錄的更改,則對GetChanges()的調用將返回null(顯然,它不會「看到」通過GUI輸入的內容)。

因此,在這兩種情況下,從舊到新或從新到舊的變化似乎引入了一些條件,使得數據表不知道輸入到GUI中的內容。但是,在從舊到新的轉換中,只需要選擇一個現有的記錄,而從新到舊的轉換隻會在保存後中斷(如果我做了一條新記錄,然後放棄它而不保存,我可以修改現有記錄而沒有問題) 。

我將此添加到保存處理程序中,就在實際保存之前(在循環中,因爲ch是一個數據表,但實際上代碼設置爲必須保存或放棄新記錄的位置,然後才能繼續 - 所以環形只執行一次):

foreach (DataSet1.HJA_VEHICLERow r in ch) 
{ 
    DataRowView drv = (DataRowView)hJA_VEHICLEBindingSource.Current; 
    MessageBox.Show(drv["VIN_ID"].ToString()); 
    MessageBox.Show(r.VEH_ID + "\n" + r.GRNTE_ID + "\n'" 
     + r.VIN_ID + "'"); 
} 

哪裏VIN_ID是這個特殊的文本框綁定到該列(我與表單上的其他字段想這太,以驗證它是不是隻是一些片狀約那一個文本框)。第一個消息框(來自綁定源的DataRowView)顯示我輸入到文本框中的vin。第二個消息框(由GetChanges()返回的表中的行)顯示VIN_ID的空字符串,雖然它具有VEH_IDGRNTE_ID的正確(通過代碼設置)值。如果我使用綁定到該列的組合框爲GRNTE_ID選擇不同的值,則會發生同樣的情況;來自數據表的行仍然具有通過代碼設置的值,「不知道」通過GUI選擇的值。

爲什麼數據表和綁定源對同一個字段有不同的值?爲什麼數據表只有在用戶從現有的切換到新的或從新的切換到現有的時候才能夠「看到」通過GUI輸入的值?

謝謝。


天使: 我做了我的服務:

public bool SaveVehicles(DataSet1.HJA_VEHICLEDataTable vehicles) 
{ 
    bool saved = false; 
    if (vehicles != null && !vehicles.HasErrors) 
    { 
     HJA_VEHICLETableAdapter ta = new HJA_VEHICLETableAdapter(); 
     int result = ta.Update(vehicles); 
     saved = (result > 0); 
    } 
    return saved; 
} 

這是從該塊被稱爲從我原來的職位:

Service<TVDDataService.IService1>.Use(svcProxy => 
{ 
    isSaved = svcProxy.SaveVehicles(ch); 
}); 

約翰內斯:

Th e調用EndEdit()是保存處理程序中的第二行(靠近我的帖子的頂部)。我應該把它叫到別的地方嗎?

謝謝。


只是爲了澄清:SaveVehicles不能成爲問題的根源,因爲問題出現之前SaveVehicles是不斷調用。什麼情況可能導致BindingSource和之間的差異 EndEdit()被調用之後,在任何實際寫入數據庫之前?

回答

1

您必須在使用EndEdit()後更新您的表格適配器;你也可以與後續的片段更新您的完整的數據集:

  this.BindingSource1.EndEdit(); 
      this.TableAdapter1.Update(this.DataSet1); 

的希望幫助...

+0

我在做這個: public bool SaveVehicles(DataSet1.HJA_VEHICLEDataTable vehicles) { bool saved = false; (vehicle!= null &&!vehicles.HasErrors) { HJA_VEHICLETableAdapter ta = new HJA_VEHICLETableAdapter(); int result = ta.Update(vehicles); saved =(result> 0); } return saved; } 這被稱爲在該塊中從原來的職位: 服務。使用(svcProxy => { isSaved = svcProxy.SaveVehicles(CH); }); – 2009-11-02 21:38:30

+0

對不起,我還在學習StackOverflow編輯/發佈的工作方式。我會把它放在原來的文章中,讓你更容易閱讀。 – 2009-11-02 21:39:12

+0

嘗試在SaveVehicles方法上放置一些錯誤並獲取流程 – 2009-11-02 22:07:22

0

*如果您正在使用的BindingSource還有: 只是做一個簡單的BindingSource.EndEdit()和您TextBox數據將被髮送到DataTable。 例子: -

_bsHeader.EndEdit(); 
if (_dsHeader.HasChanges()) 
{ 
DataTable dsInsert = _dsHeader.GetChanges(DataRowState.Added).Copy(); 
_objDal.Insert(dsInsert); 
} 

希望這有助於人誰在這裏跌倒。