&引用;并发冲突:UpdateCommand影响了预期的1条记录中的0条;从C#app更新MS Access数据库中新添加的记录时
请帮我解决问题。 尝试从用C#编写的应用程序中更新MS Access(2000格式)数据库(.mdb)中新添加的表记录时,我收到一个错误“并发冲突:UpdateCommand影响了预期的1条记录中的0条”。 这个错误是错误的,我在不同的论坛上尝试了建议的解决方案,但没有成功 以下是我一步一步做的: 我在mdb中有一个表“TRACKS”,其中包含以下列:&引用;并发冲突:UpdateCommand影响了预期的1条记录中的0条;从C#app更新MS Access数据库中新添加的记录时,c#,.net,database,ms-access,ms-access-2000,C#,.net,Database,Ms Access,Ms Access 2000,请帮我解决问题。 尝试从用C#编写的应用程序中更新MS Access(2000格式)数据库(.mdb)中新添加的表记录时,我收到一个错误“并发冲突:UpdateCommand影响了预期的1条记录中的0条”。 这个错误是错误的,我在不同的论坛上尝试了建议的解决方案,但没有成功 以下是我一步一步做的: 我在mdb中有一个表“TRACKS”,其中包含以下列: ID-键入“自动编号”(键列) 标题-“文本” 全称-“文本” 长度-“日期/时间” 我通过以下方式建立与数据库的连接并获取表记录: publ
- ID-键入“自动编号”(键列)
- 标题-“文本”
- 全称-“文本”
- 长度-“日期/时间”
- 我通过以下方式建立与数据库的连接并获取表记录:
public partial class MainForm : Form { public OleDbConnection dbConn = new OleDbConnection(); public DataSet dataset = new DataSet(); protected OleDbDataAdapter adTracks = new OleDbDataAdapter(); protected OleDbCommandBuilder cmb; ArrayList arrArtists = new ArrayList(); public MainForm(string strFileName) { InitializeComponent(); cmb = new OleDbCommandBuilder(adTracks); } private void OnLoad(object sender, EventArgs e) { dbConn.ConnectionString = Properties.Settings.Default.dbConnectionString; OleDbCommand cmTracks = new OleDbCommand("Select * from Tracks", dbConn); OleDbDataAdapter adapter = new OleDbDataAdapter(); try { dbConn.Open(); adTracks.SelectCommand = cmTracks; adTracks.Fill(dataset, "Tracks"); } catch (Exception err) { MessageBox.Show(err.Message); return; } finally { dbConn.Close(); } cboOriginal.DataSource = dataset.Tables["Tracks"]; cboOriginal.DisplayMember = "FullTitle"; cboOriginal.ValueMember = "ID"; cboOriginal.SelectedIndex = -1; adTracks.RowUpdated += new OleDbRowUpdatedEventHandler(OnRowUpdated); } }
- 然后,我使用此代码向表中添加一条新记录(
和txtTitle
控件包含该记录的值): 此代码已成功执行:将新记录添加到表中,包括mdb文件中的本地DataTable和实际表。在此处理程序中接收到键列的新自动递增值:txtgentTitle
具有此ID的行现在具有protected void OnRowUpdated(object sender, OleDbRowUpdatedEventArgs args) { if (args.StatementType == StatementType.Insert) { OleDbCommand idCMD = new OleDbCommand("SELECT @@IDENTITY", dbConn); args.Row["ID"] = (int)(idCMD.ExecuteScalar()); } }
,因此一切看起来都正常RowState==Unchanged
- 现在我想更新这个新添加的记录中的一些值(从
control): 而且它有效!数据库已更新,相应的txtLength
获取DataRow
RowState==未更改的
。 这是一个很好的解决办法。但我仍然想知道为什么“传统”方法在这里不起作用。当需要更新许多列时,解决方法并不十分方便。而且,它似乎只有在更新单行时才可以接受,并且我需要能够同时更新多行 2。推荐的尝试方法: 我替换了行
adTracks.Update(dt)代码>在步骤3中使用以下代码:
遗憾的是,行为根本没有改变-同一个错误“并发冲突:UpdateCommand影响了预期的1条记录中的0条” 以下是我在所有3个步骤中使用的代码(与原始步骤相比): 有人能说出这个生成的命令有什么问题吗?”GenreID、StyleID等是“TRACKS”表中的其他列。我不知道这些是什么意思 此外,发生异常时,以下是堆栈上的最新调用:using (OleDbDataAdapter da = new OleDbDataAdapter ("Select * from Tracks", dbConn)) { OleDbCommandBuilder cb = new OleDbCommandBuilder(da); da.RowUpdated += new OleDbRowUpdatedEventHandler(OnRowUpdated); da.Update(dt); }
at System.Data.Common.DbDataAdapter.UpdatedRowStatusErrors(RowUpdatedEventArgs rowUpdatedEvent, BatchCommandInfo[] batchCommands, Int32 commandCount) at System.Data.Common.DbDataAdapter.UpdatedRowStatus(RowUpdatedEventArgs rowUpdatedEvent, BatchCommandInfo[] batchCommands, Int32 commandCount) at System.Data.Common.DbDataAdapter.Update(DataRow[] dataRows, DataTableMapping tableMapping) at System.Data.Common.DbDataAdapter.UpdateFromDataTable(DataTable dataTable, DataTableMapping tableMapping) at System.Data.Common.DbDataAdapter.Update(DataTable dataTable) at *my code as above*
用以下方法替换
方法:OnLoad
然后是更新数据集的代码: (注意,我更正了我在上面的评论中对adTracks的错误引用。)private void OnLoad(object sender, EventArgs e) { dbConn.ConnectionString = Properties.Settings.Default.dbConnectionString; try { dbConn.Open(); adTracks = new OleDbDataAdapter("Select * from Tracks", dbConn)); adTracks.Fill(dataset,"Tracks"); } catch (Exception err) { MessageBox.Show(err.Message); return; } finally { dbConn.Close(); } cboOriginal.DataSource = dataset.Tables["Tracks"]; cboOriginal.DisplayMember = "FullTitle"; cboOriginal.ValueMember = "ID"; cboOriginal.SelectedIndex = -1; adTracks.RowUpdated += new OleDbRowUpdatedEventHandler(OnRowUpdated); }
用以下方法替换
方法:OnLoad
然后是更新数据集的代码: (注意,我更正了我在上面的评论中对adTracks的错误引用。)private void OnLoad(object sender, EventArgs e) { dbConn.ConnectionString = Properties.Settings.Default.dbConnectionString; try { dbConn.Open(); adTracks = new OleDbDataAdapter("Select * from Tracks", dbConn)); adTracks.Fill(dataset,"Tracks"); } catch (Exception err) { MessageBox.Show(err.Message); return; } finally { dbConn.Close(); } cboOriginal.DataSource = dataset.Tables["Tracks"]; cboOriginal.DisplayMember = "FullTitle"; cboOriginal.ValueMember = "ID"; cboOriginal.SelectedIndex = -1; adTracks.RowUpdated += new OleDbRowUpdatedEventHandler(OnRowUpdated); }
在并发性方面也有同样的问题。什么都没用。 2天后,我看到了这篇关于Ms Access和数据类型decimal的文章。 本文声明应该避免使用这种数据类型 因此,我使用数据类型Double重新设计了表。用新名称保存它。复制了数据,最后用旧名称重命名了新表 在Visual Studio中,我删除了Dataset.xsd并添加了一个新的Dataset 终于成功了 请阅读:
在并发性方面也有同样的问题。什么都没用。 2天后,我看到了这篇关于Ms Access和数据类型decimal的文章。 本文声明应该避免使用这种数据类型 因此,我使用数据类型Double重新设计了表。用新名称保存它。复制了数据,最后用旧名称重命名了新表 在Visual Studio中,我删除了Dataset.xsd并添加了一个新的Dataset 终于成功了 请阅读:
检查此站点:当使用DataAdapter更新数据集时,我倾向于使用以下方法:
@krish我知道这个链接。在我的情况下,没有并发性,我的应用程序是唯一一个一次访问数据库的应用程序,并且不会删除任何记录。因此,遗憾的是,这篇文章中描述的情况在这里不适用。您可以尝试标准的SQL执行吗?将字符串更新命令发送到database@krish你的意思是删除OleDbCommandBuilder并自己创建更新命令(“更新轨迹集…”)?检查此站点:当使用DataAdapter更新数据集时,我倾向于使用以下方法:使用(OleDbDataAdapter da=new-OleDbDataAdapter(“Select*from Tracks”,dbConn)){OracleCommandBuilder cb=new-OracleCommandBuilder(adTracks);adTracks.Update(dataset,dataset.Tables[“Tracks”]);}
@krish我知道这个链接。在我的情况下,没有并发,我的应用程序是唯一一个一次访问数据库的应用程序,并且没有记录被删除。因此,遗憾的是,这篇文章中描述的情况在这里不适用。你能尝试标准SQL执行吗?一个字符串更新命令到database@krish你的意思是放弃OleDbCommandBu吗ilder和自己创建update命令(“更新轨迹集…”)?检查此站点:使用DataAdapter更新数据集时,我倾向于使用以下方法:使用(OleDbDataAdapter da=新OleDbDataAdapter(“从轨迹中选择*,dbConn)){OracleCommandBuilder cb=new OracleCommandBuilder(adTracks);adTracks.Update(dataset,dataset.Tables[“Tracks”]);}
@krish我知道这个链接。在我的情况下,没有并发,我的应用程序是唯一一个一次访问数据库的应用程序,并且没有记录被删除。因此,遗憾的是,这篇文章中描述的情况在这里不适用。你能尝试标准SQL执行吗?一个字符串更新命令到database@krish你的意思是放弃OleDbCommandBu吗ilder与upda的创建使用(OleDbDataAdapter da=new OleDbDataAdapter(“Select*from Tracks”,dbConn)){OracleCommandBuilder cb=new OracleCommandBuilder(adTracks);adTracks.update(dataset,dataset.Tables[“Tracks”];}
1. public partial class MainForm : Form { public OleDbConnection dbConn = new OleDbConnection(); public DataSet dataset = new DataSet(); protected OleDbDataAdapter adTracks = new OleDbDataAdapter(); ArrayList arrArtists = new ArrayList(); public MainForm(string strFileName) { InitializeComponent(); } private void OnLoad(object sender, EventArgs e) { dbConn.ConnectionString = Properties.Settings.Default.dbConnectionString; try { dbConn.Open(); adTracks = new OleDbDataAdapter("Select * from Tracks", dbConn)); adTracks.Fill(dataset,"Tracks"); } catch (Exception err) { MessageBox.Show(err.Message); return; } finally { dbConn.Close(); } cboOriginal.DataSource = dataset.Tables["Tracks"]; cboOriginal.DisplayMember = "FullTitle"; cboOriginal.ValueMember = "ID"; cboOriginal.SelectedIndex = -1; adTracks.RowUpdated += new OleDbRowUpdatedEventHandler(OnRowUpdated); } } 2. DataTable dt; DataRow dr; int newID; dt = dataset.Tables["Tracks"]; dr = dt.NewRow(); dr["Title"] = txtTitle.Text; dr["FullTitle"] = txtGenTitle.Text; dt.Rows.Add(dr); try { dbConn.Open(); using (OleDbDataAdapter da = new OleDbDataAdapter ("Select * from Tracks", dbConn)) { OleDbCommandBuilder cb = new OleDbCommandBuilder(da); da.RowUpdated += new OleDbRowUpdatedEventHandler(OnRowUpdated); da.Update(dataset, "Tracks"); } } catch (Exception err) { MessageBox.Show("Error adding new track '" + txtGenTitle.Text + "':\n" + err.Message); return; } finally { dbConn.Close(); } res = dt.Select("FullTitle = '" + txtGenTitle.Text.Replace("'", "''") + "'"); if (res.Length != 0) { newID = (int)res[0]["ID"]; // continue with newID } 3. DataTable dt; DataRow dr; DataRow[] res; dt = dataset.Tables["Tracks"]; res = dt.Select("FullTitle = '" + txtGenTitle.Text.Replace("'", "''") + "'"); if (res.Length != 0) { TimeSpan tsNew = TimeSpan.Zero, tsOld = TimeSpan.Zero; if (txtLength.Text != String.Empty) tsNew = TimeSpan.Parse(txtLength.Text); if (!(res[0]["Length"] is DBNull)) { DateTime date = (DateTime)res[0]["Length"]; tsOld = date.TimeOfDay; } if (tsNew != TimeSpan.Zero && (tsOld == TimeSpan.Zero || tsOld.CompareTo(tsNew) < 0)) { if (tsNew != TimeSpan.Zero && (tsOld == TimeSpan.Zero || tsOld.CompareTo(tsNew) < 0)) res[0]["Length"] = txtLength.Text; if (String.Compare((string)res[0]["Title"], txtTitle.Text, true) != 0) { res[0]["Title"] = txtTitle.Text; res[0]["FullTitle"] = txtGenTitle.Text; } try { dbConn.Open(); using (OleDbDataAdapter da = new OleDbDataAdapter ("Select * from Tracks", dbConn)) { OleDbCommandBuildercb = new OleDbCommandBuilder(da); da.Update(dataset , "Tracks"); } } catch (Exception err) { MessageBox.Show("Error updating track '" + txtGenTitle.Text + "':\n" + err.Message); return; } finally { dbConn.Close(); } } }
UPDATE Tracks SET Length = ? WHERE ((ID = ?) AND ((? = 1 AND Title IS NULL) OR (Title = ?)) AND ((? = 1 AND FullTitle IS NULL) OR (FullTitle = ?)) AND ((? = 1 AND GenreID IS NULL) OR (GenreID = ?)) AND ((? = 1 AND StyleID IS NULL) OR (StyleID = ?)) AND ((? = 1 AND SubStyleID IS NULL) OR (SubStyleID = ?)) AND ((? = 1 AND Length IS NULL) OR (Length = ?)) AND ((? = 1 AND UseOriginal IS NULL) OR (UseOriginal = ?)) AND ((? = 1 AND Version IS NULL) OR (Version = ?)) AND ((? = 1 AND TrackID IS NULL) OR (TrackID = ?)) AND ((? = 1 AND SpecPresConjunctor IS NULL) OR (SpecPresConjunctor = ?)) AND ((? = 1 AND SpecFeatConjunctor IS NULL) OR (SpecFeatConjunctor = ?)) AND ((? = 1 AND FreeRecord IS NULL) OR (FreeRecord = ?)))
at System.Data.Common.DbDataAdapter.UpdatedRowStatusErrors(RowUpdatedEventArgs rowUpdatedEvent, BatchCommandInfo[] batchCommands, Int32 commandCount) at System.Data.Common.DbDataAdapter.UpdatedRowStatus(RowUpdatedEventArgs rowUpdatedEvent, BatchCommandInfo[] batchCommands, Int32 commandCount) at System.Data.Common.DbDataAdapter.Update(DataRow[] dataRows, DataTableMapping tableMapping) at System.Data.Common.DbDataAdapter.UpdateFromDataTable(DataTable dataTable, DataTableMapping tableMapping) at System.Data.Common.DbDataAdapter.Update(DataTable dataTable) at *my code as above*
private void OnLoad(object sender, EventArgs e) { dbConn.ConnectionString = Properties.Settings.Default.dbConnectionString; try { dbConn.Open(); adTracks = new OleDbDataAdapter("Select * from Tracks", dbConn)); adTracks.Fill(dataset,"Tracks"); } catch (Exception err) { MessageBox.Show(err.Message); return; } finally { dbConn.Close(); } cboOriginal.DataSource = dataset.Tables["Tracks"]; cboOriginal.DisplayMember = "FullTitle"; cboOriginal.ValueMember = "ID"; cboOriginal.SelectedIndex = -1; adTracks.RowUpdated += new OleDbRowUpdatedEventHandler(OnRowUpdated); }
using (OleDbDataAdapter da = new OleDbDataAdapter ("Select * from Tracks", dbConn)) { OracleCommandBuilder cb = new OracleCommandBuilder(da); da.Update(dataset , "Tracks"); }