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文件没有任何变化,并且它没有意识到这些是全新的行。数据库我正在尝试将数据放入。