C# BindingSource看到更改,DataTable没有

C# BindingSource看到更改,DataTable没有,c#,data-binding,bindingsource,C#,Data Binding,Bindingsource,我最近从Java/RMI转换到了C/.net,并且正在进行我的第一个项目,使用数据绑定来更新Oracle中的记录。在我正在构建的第一个表单上,我有一个详细视图,可以查看车辆记录VIN、年份/品牌/型号、车牌号等等。我写数据库的第一件事就是保存更新: private void btn_saveDesc_Click(object sender, EventArgs e) { bool isSaved = false; hJA_VEHICLEBindingSource.EndEdit(

我最近从Java/RMI转换到了C/.net,并且正在进行我的第一个项目,使用数据绑定来更新Oracle中的记录。在我正在构建的第一个表单上,我有一个详细视图,可以查看车辆记录VIN、年份/品牌/型号、车牌号等等。我写数据库的第一件事就是保存更新:

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.");
        }
    }
}
所以在上面,我将初始值放入一些必需的列中,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输入的内容

因此,在这两种情况下,从旧到新或从新到旧的更改似乎引入了一些条件,使得datatable不知道输入GUI的内容。但在从旧记录更改为新记录时,只需选择现有记录,而在从新记录更改为旧记录时,只有在保存新记录后才会中断,但如果在不保存的情况下放弃它,则可以毫无问题地修改现有记录

我将其添加到save处理程序中,就在循环中实际保存之前,因为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_ID和GRNTE_ID的代码值进行了正确设置。如果我使用绑定到该列的组合框为GRNTE_ID选择不同的值,也会发生同样的情况;datatable中的行仍然具有通过代码设置的值,而不知道通过GUI选择的值

为什么datatable和绑定源对同一字段有不同的值?为什么只有在用户从现有切换到新,或从新切换到现有之前,datatable才能看到通过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); 
}); 
约翰尼斯:

对EndEdit的调用是我文章顶部附近保存处理程序中的第二行。我应该在别的地方叫它吗

谢谢


只是想澄清一下:SaveVehicles不能成为问题的根源,因为问题出现在savehicles被调用之前。在调用EndEdit之后,在任何东西实际写入数据库之前,什么情况会导致BindingSource和DataTable之间出现差异?

使用EndEdit之后,您必须更新表适配器;您还可以使用以下代码段更新完整的数据集:

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

希望有助于…

*如果您同时使用BindingSource: 只需执行一个简单的BindingSource.EndEdit,您的文本框数据就会发送到DataTable。 例如:-

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

希望这能帮助在这里遇到困难的人。

我在这里这样做:public bool savevehicles dataset1.HJA_VEHICLEDataTable vehicles{bool saved=false;if vehicles!=null&!vehicles.hasrerrors{HJA_VEHICLETableAdapter ta=new HJA_VEHICLETableAdapter;int result=ta.updatehicles;saved=result>0;}return saved;}这是在我的原始帖子中在此块中调用的:Service.UsesvcProxy=>{isSaved=svcProxy.SaveVehiclesch;};抱歉,我仍在学习StackOverflow编辑/发布的工作原理。我会把这篇文章放在我的原始文章中,让你更容易阅读。尝试在SaveVehicle方法上添加一些中断,然后获取流可能isSaved返回false,无论尝试使用视觉研究的观察者如何。调用SaveVehicle之前问题很明显从GetChanges返回的datatable已经缺少通过GUI输入的值。SaveVehicles方法保存 传递给它的变更数据表中有什么,在有问题的情况下,缺少通过GUI输入的值。传递给SaveVehciles方法的内容将被保存,并返回true。问题是原始帖子顶部的save按钮处理程序的第三行中的GetChanges返回的值丢失/未更改。谢谢-
_bsHeader.EndEdit();
if (_dsHeader.HasChanges())
{
DataTable dsInsert = _dsHeader.GetChanges(DataRowState.Added).Copy();
_objDal.Insert(dsInsert);
}