SQLiteDataAdapter Update method returning 0

后端 未结 2 950
独厮守ぢ
独厮守ぢ 2021-01-06 06:13

I loaded 83 rows from my CSV file, but when I try to update the SQLite database I get 0 rows... I can\'t figure out what I\'m doing wrong.

The program outputs:

相关标签:
2条回答
  • 2021-01-06 06:49

    Update:

    After reading your solution let me say that I am embarrased that I did not catch that. Enumerating rows to set rowstate to added will work.

    But let me give you a cleaner way to do that using 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);
        }
    

    This imports 83 rows:

    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();
            }
        }
    }
    

    Original Answer:

    This is the source of the SQLiteDataAdapter ctor that ultimately gets called. Note that no command builder is employed. You need to explicitly set the InserCommand property on the SQLiteDataAdapter, perhaps by using a SQLiteCommandBuilder?

    public SQLiteDataAdapter(string commandText, SQLiteConnection connection)
    {
        this.SelectCommand = new SQLiteCommand(commandText, connection);
    }
    
    0 讨论(0)
  • 2021-01-06 06:59

    I was able to get around the issue by going through each row and changing it's state by calling SetAdded();... after I did that the Update command worked like a charm.

    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);
    }
    

    I assume that when the DataSet is filled from the CSV file and I then I attempt to call Update in order to insert the data into the database, the state of the row does not indicate any changes. We have to tell the DataAdapter that there is a change in the DataSet because all it sees is that are no changes to the DataSet with respect to the CSV file it was populated from and it doesn't realize that these are brand new rows for the database I'm trying to put the data in.

    0 讨论(0)
提交回复
热议问题