SQLiteDataAdapter Update方法返回0

我从我的CSV文件中加载了83行,但是当我尝试更新SQLite数据库时,我得到0行……我无法弄清楚我做错了什么。

该方案产出:

Num rows loaded is 83 Num rows updated is 0 

源代码是:

 public void InsertData(String csvFileName, String tableName) { String dir = Path.GetDirectoryName(csvFileName); String name = Path.GetFileName(csvFileName); using (OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + dir + @";Extended Properties=""Text;HDR=Yes;FMT=Delimited""")) { conn.Open(); using (OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM " + name, conn)) { QuoteDataSet ds = new QuoteDataSet(); adapter.Fill(ds, tableName); Console.WriteLine("Num rows loaded is " + ds.Tags.Rows.Count); InsertData(ds, tableName); } } } public void InsertData(QuoteDataSet data, String tableName) { using (SQLiteConnection conn = new SQLiteConnection(_connectionString)) { using (SQLiteDataAdapter sqliteAdapter = new SQLiteDataAdapter("SELECT * FROM " + tableName, conn)) { using (new SQLiteCommandBuilder(sqliteAdapter)) { conn.Open(); Console.WriteLine("Num rows updated is " + sqliteAdapter.Update(data, tableName)); } } } } 

有关为何没有更新正确行数的任何提示?

更新:

我试着在调用update之前设置命令,我仍然遇到同样的问题……代码现在是:

 sqliteAdapter.InsertCommand = cmndBldr.GetInsertCommand(); Console.WriteLine("Num rows updated is " + sqliteAdapter.Update(data, tableName)); 

当我调试它时,命令文本是: _commandText = "INSERT INTO [Tags] ([tagId], [tagName], [description], [colName], [dataType], [realTime]) VALUES (@param1, @param2, @param3, @param4, @param5, @param6)"

这是一个以xml格式显示数据集状态的贴图: http ://pastie.org/936882

更新

在阅读完解决方案之后,让我说我很尴尬,我没有抓住它。 枚举行以将rowstate设置为添加将起作用。

但是,让我使用adapter.AcceptChangesDuringFill为您提供更清晰的方法。

  using (OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM " + name, conn)) { // this is the proper way to transfer rows adapter.AcceptChangesDuringFill = false; QuoteDataSet ds = new QuoteDataSet(); adapter.Fill(ds, tableName); Console.WriteLine("Num rows loaded is " + ds.Tags.Rows.Count); InsertData(ds, tableName); } 

这导入83行:

Program.cs中

 using System; using System.Data; using System.Data.SQLite; namespace SqliteCsv { internal class Program { private static void Main(string[] args) { // fill your dataset QuoteDataSet ds = new QuoteDataSet(); ds.ReadXml("data.xml", XmlReadMode.InferTypedSchema); // hack to flag each row as new as per lirik // OR just set .AcceptChangesDuringFill=false on adapter foreach (DataTable table in ds.Tables) { foreach (DataRow row in table.Rows) { row.SetAdded(); } } int insertedRows; using ( SQLiteConnection con = new SQLiteConnection(@"data source=C:\Projects\StackOverflowAnswers\SqliteCsv\SqliteCsv\Quotes.db")) { con.Open(); // clear table - you may not want this SQLiteCommand cmd = con.CreateCommand(); cmd.CommandText = "delete from Tags"; cmd.ExecuteNonQuery(); using (SQLiteTransaction txn = con.BeginTransaction()) { using (SQLiteDataAdapter dbAdapter = new SQLiteDataAdapter("select * from Tags", con)) { dbAdapter.InsertCommand = new SQLiteCommandBuilder(dbAdapter).GetInsertCommand(true); insertedRows = dbAdapter.Update(ds, "Tags"); } txn.Commit(); } } Console.WriteLine("Inserted {0} rows", insertedRows); Console.WriteLine("Press any key"); Console.ReadKey(); } } } 

原答案:

这是最终被调用的SQLiteDataAdapter ctor的源代码。 请注意,不使用命令构建器。 您需要在SQLiteDataAdapter上显式设置InserCommand属性,可能使用SQLiteCommandBuilder?

 public SQLiteDataAdapter(string commandText, SQLiteConnection connection) { this.SelectCommand = new SQLiteCommand(commandText, connection); } 

通过调用SetAdded();我可以通过遍历每一行并改变它的状态来解决这个问题SetAdded(); …在我这样做之后,Update命令就像魅力一样。

 public void InsertData(QuoteDataSet dataSet, String tableName) { int numRowsUpdated = 0; using (SQLiteConnection conn = new SQLiteConnection(_connectionString)) { conn.Open(); using (SQLiteTransaction transaction = conn.BeginTransaction()) using (SQLiteDataAdapter sqliteAdapter = new SQLiteDataAdapter("SELECT * FROM " + tableName, conn)) { using (sqliteAdapter.InsertCommand = new SQLiteCommandBuilder(sqliteAdapter).GetInsertCommand()) { var rows = dataSet.Tags.AsEnumerable(); foreach (var row in rows) { row.SetAdded(); } numRowsUpdated = sqliteAdapter.Update(dataSet, tableName); } transaction.Commit(); } } Console.WriteLine("Num rows updated is " + numRowsUpdated); } 

我假设当从CSV文件填充DataSet然后我尝试调用Update以便将数据插入数据库时​​,行的状态不表示任何更改。 我们必须告诉DataAdapter DataSet中有一个更改,因为它看到的是DataSet相对于它填充的CSV文件没有任何变化,并且它没有意识到这些是全新的行。数据库我正在尝试将数据放入。