SQLiteDataAdapter 更新方法返回 0

发布于 2024-08-30 02:26:58 字数 1966 浏览 10 评论 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));
            }
        }
    }
}

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

更新:

我尝试在调用更新之前设置命令,但仍然遇到同样的问题...代码现在是:

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

当我调试它时,命令文本是:_commandText = "插入 [标签] ([tagId]、[tagName]、[描述]、[colName]、[dataType]、[realTime]) 值 (@param1、@param2、@param3、@param4、@param5、@param6) "

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

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:

Num rows loaded is 83
Num rows updated is 0

The source code is:

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

Any hints on why it's not updating the correct number of rows?

Update:

I tried to set the command before calling update and I'm still getting the same issue... the code is now:

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

When I debug it the command text is: _commandText = "INSERT INTO [Tags] ([tagId], [tagName], [description], [colName], [dataType], [realTime]) VALUES (@param1, @param2, @param3, @param4, @param5, @param6)"

Here is a pastie showing the state of dataset in xml format: http://pastie.org/936882

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

记忆消瘦 2024-09-06 02:26:58

更新

读完你的解决方案后,让我说,我很尴尬,因为我没有明白这一点。枚举行以将行状态设置为添加将起作用。

但是,让我为您提供一种使用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 构造函数的源代码。请注意,没有使用命令生成器。您需要在 SQLiteDataAdapter 上显式设置 InserCommand 属性,也许可以使用 SQLiteCommandBuilder?

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

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);
}
挽袖吟 2024-09-06 02:26:58

我能够通过遍历每一行并通过调用 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 文件,它没有意识到这些是我试图将数据放入的数据库的全新行。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文