代码之家  ›  专栏  ›  技术社区  ›  Kiril

sqliteDataAdapter更新方法返回0

  •  4
  • Kiril  · 技术社区  · 15 年前

    我从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

    2 回复  |  直到 15 年前
        1
  •  2
  •   Sky Sanders    15 年前

    更新 :

    在阅读了你的解决方案之后,让我说,我很困惑,我没有理解。枚举行以设置要添加的行状态将有效。

    但让我用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行:

    程序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);
    }
    
        2
  •  1
  •   Kiril    15 年前

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

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

    我想当 DataSet 是从csv文件填充的,然后我尝试调用 Update 为了将数据插入数据库,行的状态不指示任何更改。我们必须告诉 DataAdapter 有一个变化 数据集 因为它所看到的只是 数据集 关于从中填充的csv文件,它没有意识到这些是我试图放入数据的数据库的全新行。

    推荐文章