操作DataTable中动态的行,一点收集整理资料。
一、怎么删除动态的DT中的指定行
采用datatable.Rows[i].Delete()删除行后再访问该表时出现出现“不能通过已删除的行访问该行的信息”的错误。
原因如下:
Delete()之后需要datatable.AccepteChanges()方法确认完全删除,因为Delete()只是将相应列的状态标志为删除,还可以通过datatable.RejectChanges()回滚,使该行取消删除。
所以如果要彻底删除datarow,需要Delete()和AccepteChanges()方法同时使用,或者采用datatable.Rows.RemoveAt(i)方法直接删除,其中i表示行索引,还有一个就是datatable.Rows.Remove(DataRow dr)删除指定行。
不过使用datatable.Rows.RemoveAt(i)要注意,如果连续使用datatable.Rows.RemoveAt(0);datatable.Rows.RemoveAt(1);这时并不是删除了原表中的0,1行,而是删除0行后,原来的1行就变成了0行,所以datatable.Rows.RemoveAt(1)实际删除的是原表的2行。
所以还是要慎用datatable.Rows.RemoveAt(i),若要删除多行,可以连续用Delete(),然后采用AccepteChanges()方法确认删除。
一点补充说明:
1、使用Remove()类似使用Delete()方法后,再调用AccepteChanges()方法
2、如果该行的 RowState 为 Added,则在调用 AcceptChanges 时,RowState 将变为 Detached,并且将从表中移除该行。
在对现有的 DataRow 使用 Delete 方法后,RowState 将变为 Deleted。在调用 AcceptChanges 之前,它一直保持为 Deleted。此时,将从表中移除 DataRow。可通过调用 RejectChanges 取消删除行。
3、确实要删除(以后不想恢复的话)
Eg:
(1)
DataRow.Delete()后要记住AcceptChanges
DataRow[] drs = DataTabl1.Select("id=2 or id=4");
for( int i=0 ; i<drs.Count ; i++ )
{
DataTable1.Rows.Remove( drs[i] );
}
(2)
System.Data.DataTable dt = this.ImportExcelToDataTable(stateDTO.OpenFileName);
this.ExcelDTCount = dt.Rows.Count;
System.Data.DataTable edt = dt.Copy();
CensusData_TempModel cdModel = new CensusData_TempModel();
try
{
for (int i = 0; i < dt.Rows.Count; i++)
{
cdModel.CensusName = dt.Rows[i][0].ToString();
cdModel.CensusCompany = dt.Rows[i][32].ToString();
CensusDataOutPutService.Insert_TempCensusData(cdModel);//先插入到临时表
edt.Rows[i].Delete();
}
edt.AcceptChanges();
CensusDataOutPutService.InsertTrueCensusData();//在解析插入到真实表
}
catch
{
edt.AcceptChanges();
CensusDataOutPutService.InsertTrueCensusData();//解析插入到真实表
二、动态为表格新增,删除行
这是我个人的一个办法,应该还有其他更好的办法。
1。新增行
在页面上定义一个DataTable,将需要绑定的数据源照搬拷贝一份DataTable dt=GetTable().Copy();后面的函数为调用返回DT的方法。然后将页面的数据源控件绑定到此定义的DT中,下面是一个添加的例子,如果表格中有此数据,则不能新增(定义了一个布耳型的变量来判断)
bool isHave = false;
foreach (GridViewRow grdRow in this.GrdSupplierInfo.Rows)
{
//如果记录集中有此供应商则不能添加
if (grdRow.Cells[2].Text.ToString().Equals(txtSupplierName.Text.Trim()))
isHave = true;
if (isHave == true)
break;
}
if (isHave == true)
{
RegisterClientScriptBlock("error", "<script>alert('你已经添加过该供应商!')</script>");
}
else
{
//将供应商添加到表格中,重新绑定数据集,动态显示
Supplier si = new Supplier();
DataTable tempDT = si.SupplierSelect(txtSupplierName.Text.Trim());
foreach (DataRow dr in tempDT.Rows)
{
dt.ImportRow(dr);
}
GrdProductInfo.DataSource = dt;
GrdSupplierInfo.DataSource = dt;
GrdProductInfo.DataBind();
GrdSupplierInfo.DataBind();
}
2。删除行
定义了一个变量,如果表格里没有此数据则不能删除,我这里面涉及到一点业务上的限制,不能将其数据全部删除,然后再添加,各位可根据自己情况继续做扩充。
bool isHave = false;
foreach (GridViewRow grdRow in this.GrdProductInfo.Rows)
{
//如果记录集中有此供应商则可以删除
if (grdRow.Cells[2].Text.ToString().Equals(txtSupplierName.Text.Trim()))
isHave = true;
if (isHave == true)
break;
}
if (isHave == false)
{
RegisterClientScriptBlock("error", "<script>alert('该供应商不在此列,请重新选择!')</script>");
}
else
{
//将供应商信息在表格中删除,重新绑定,动态显示
//如果只有一个供应商时,则最后一家不能删除
if (GrdSupplierInfo.Rows.Count == 1)
{
RegisterClientScriptBlock("error", "<script>alert('该供应商不能删除,应确保有一家供应商 !')</script>");
}
Supplier si = new Supplier();
DataTable tempDT = si.SupplierSelect(txtSupplierName.Text.Trim());
foreach (DataRow dr in tempDT.Rows)
{
dt.Rows.Remove(dr);
}
GrdProductInfo.DataSource = dt;
GrdSupplierInfo.DataSource = dt;
GrdProductInfo.DataBind();
GrdSupplierInfo.DataBind();
}
三、C#中的DataTable怎么获取已删除行的信息
说明:这里所说的删除的行,是指你的DataTable中的行删除后,还没有AcceptChanges()。代码如下,很简单:
//获取所有删除的行
System.Data.DataRow[] drs = dataTable.Select("", "", System.Data.DataViewRowState.Deleted);
//获取删除的第一行的第一列的原始值
drs[0][0, System.Data.DataRowVersion.Original]