通过Adapter.Update将DataTable保存到SQLite数据库

时间:2013-12-06 08:48:22

标签: c# wpf sqlite datagrid datatable

我写了SQLite包装类 像这样

using System;
using System.Data;
using System.Data.SQLite;

namespace SuPOS.Sources
{
public class SQLITE
    {
    private SQLiteConnection con;
    private SQLiteCommand cmd;
    private SQLiteDataAdapter adapter;

    public SQLITE(string databasename)
        {
        con = new SQLiteConnection(string.Format("Data Source={0};Compress=True;", databasename));
        }
    public int Execute(string sql_statement)
        {
        con.Open();
        cmd = con.CreateCommand();
        cmd.CommandText = sql_statement;
        int row_updated;
        try
            {
            row_updated = cmd.ExecuteNonQuery();
            }
        catch
            {
            con.Close();
            return 0;
            }
        con.Close();
        return row_updated;
        }
    public DataTable GetDataTable(string tablename)
        {
        DataTable DT = new DataTable();
        con.Open();
        cmd = con.CreateCommand();
        cmd.CommandText = string.Format("SELECT * FROM {0}", tablename);
        adapter = new SQLiteDataAdapter(cmd);
        adapter.AcceptChangesDuringFill = false;
        adapter.Fill(DT);
        con.Close();
        DT.TableName = tablename;
        return DT;
        }
    public void SaveDataTable(DataTable DT)
        {
        try
            {
            Execute(string.Format("DELETE FROM {0}", DT.TableName));
            con.Open();
            cmd = con.CreateCommand();
            cmd.CommandText = string.Format("SELECT * FROM {0}", DT.TableName);
            adapter = new SQLiteDataAdapter(cmd);
            SQLiteCommandBuilder builder = new SQLiteCommandBuilder(adapter);
            adapter.Update(DT);
            con.Close();
            }
        catch (Exception Ex)
            {
            System.Windows.MessageBox.Show(Ex.Message);
            }
        }
    }
}

我通过“GetDataTable”从数据库中检索DataTable 并绑定到WPF中的control.itemsource,例如DataGrid
我可以在DataGrid上添加新行并正确保存到数据库中 我可以更改任何列并正确保存到数据库中

但问题是, 当我向DataGrid插入新行并像往常一样调用“SaveDataTable”时 我可以妥善保存..然后我改变那一行的一些列
现在,当我使用“SaveDataTable”时,它就像这张图片一样说

enter image description here

出现此消息后,
当我打电话给“SaveDataTable”时,它会像这张照片一样说

enter image description here

2 个答案:

答案 0 :(得分:3)

最后,我找到了解决方案。

问题来自于我调用Fill(DataTable)后每行的rowstate,填充后DataTable中的每个DataRow都在RowState中“添加”。

因此我无法调用“Update(DataTable)”,因为它会将DataTable中的每一行插入到数据库中。 因此,在我的包装器类中,我必须在“Update(DataTable)”之前删除数据库中的所有行。

所以,我必须通过“AcceptChanges”方法在方法Fill(DataTable)之后的每个DataRow中更改RowState。

   public DataTable GetDataTable(string tablename)
        {
        DataTable DT = new DataTable();
        con.Open();
        cmd = con.CreateCommand();
        cmd.CommandText = string.Format("SELECT * FROM {0}", tablename);
        adapter = new SQLiteDataAdapter(cmd);
        adapter.AcceptChangesDuringFill = false;
        adapter.Fill(DT);
        con.Close();
        DT.TableName = tablename;
        foreach (DataRow row in DT.Rows)
            {
            row.AcceptChanges();
            }
        return DT;
        }
    public void SaveDataTable(DataTable DT)
        {
        try
            {
            con.Open();
            cmd = con.CreateCommand();
            cmd.CommandText = string.Format("SELECT * FROM {0}", DT.TableName);
            adapter = new SQLiteDataAdapter(cmd);
            SQLiteCommandBuilder builder = new SQLiteCommandBuilder(adapter);
            adapter.Update(DT);
            con.Close();
            }
        catch (Exception Ex)
            {
            System.Windows.MessageBox.Show(Ex.Message);
            }
        }

现在我不必在更新前删除所有行,问题就不存在了。

答案 1 :(得分:3)

我知道这是一个旧线程,但您为解决方案编写的额外代码只能用于取消代码中的错误,您可以在其中设置:

adapter.AcceptChangesDuringFill = false ; /* default is 'true' */

如果删除上面的行,则不再需要让行接受更改,并且您的方法会更清晰:

public DataTable GetDataTable(string tablename)
{
    DataTable DT = new DataTable();
    con.Open();
    cmd = con.CreateCommand();
    cmd.CommandText = string.Format("SELECT * FROM {0}", tablename);
    adapter = new SQLiteDataAdapter(cmd);
    adapter.Fill(DT);
    con.Close();
    DT.TableName = tablename;
    return DT;
}