【问题标题】:C#: Deleting row in DataTable does not apply to data bankC#:删除DataTable中的行不适用于数据库
【发布时间】:2017-07-10 05:04:53
【问题描述】:

我的任务应该很简单,但经过几个小时后,我必须承认我完全陷入困境!

我只想从datatable 中删除datarow。我的数据表是 SQLite 数据库中我当前数据集中的表的副本。必须使用table.row.Delete() 方法。我知道delete() 只是标记要在表更新时删除的行。

下面是我目前使用的代码:

我通过以下方式检索我的数据:

    public DataTable GetTable(string tableName)
    {
        string connectionPath = dbVariables.ConnectionString;

        try
        {

            SQLiteConnection myConnection = new  SQLiteConnection(connectionPath);

            myConnection.Open();
            string cmdStr = "SELECT * FROM " + tableName;

            DataTable myTable = new DataTable();
            SQLiteDataAdapter myAdapter = new SQLiteDataAdapter(cmdStr, myConnection);

            myAdapter.FillSchema(myTable, SchemaType.Source); 

            myTable.Columns[dbVariables.ClassesID].AutoIncrement = true; 
            myTable.Columns[dbVariables.ClassesID].AutoIncrementSeed = 1; 
            myTable.Columns[dbVariables.ClassesID].AutoIncrementStep = 1; 

            myAdapter.Fill(myTable);

            myConnection.Close();

            return myTable;

        }
        catch (SQLiteException e)
        {
            MessageBox.Show(e.ToString());
            return null;
        }
    }

我在这里操作我的数据:

if (myResult == DialogResult.Yes)
{
    //killTable.AcceptChanges();
    DataRow[] dr = killTable.Select("" + cmVariables.ClassName + " = '" + cmbClasses.Text + "'");

    //First I need to evaluate the row index of the row I want to delete
    string indexName = (killTable.Rows.IndexOf(dr[0])).ToString();
    int i = Int32.Parse(indexName);

    // And we are done - I got my row index
    DataRow modifiedRow = killTable.Rows[i];

    killTable.Rows[i].Delete();

    //I inserted this messagebox just to see the rowstatus - and yes, it is marked as deleted on runtime...
    MessageBox.Show(killTable.Rows[i].RowState);

    // I refer to this in the text below
    killTable.AcceptChanges();

    killClass_Execution(killTable, cmbClasses.Text, ShortClassNm);
}

至少还有将我的数据表更新回数据库的代码:

public void UpdateTable(string tableName, DataTable sourceTable, bool newOrEdit)
    {          
        try
        {
            string connectionPath = dbVariables.ConnectionString;
            //Connection erstellen --> der connectString gibt dabei den Pfad an.
            SQLiteConnection myConnection = new SQLiteConnection(connectionPath);

            myConnection.Open();

            //Einen Befehls-String erstellen, der das UPDATE-Command auslöst
            // UPDATE cm_ClassTest SET className = userEditInput WHERE className = 'oldClassName'
            string myUpdateString = "SELECT * FROM " + tableName + "";

            SQLiteDataAdapter myAdapter = new SQLiteDataAdapter(myUpdateString, myConnection);

            SQLiteCommandBuilder comBuild = new SQLiteCommandBuilder(myAdapter);

            myAdapter.DeleteCommand = comBuild.GetDeleteCommand(true);
            myAdapter.UpdateCommand = comBuild.GetUpdateCommand(true);
            myAdapter.InsertCommand = comBuild.GetInsertCommand(true);

            myAdapter.Update(sourceTable);

            myConnection.Close();

            if (newOrEdit == true)
            {
                MessageBox.Show("Klasse erstellt!");
            }
            else
            {
                MessageBox.Show("Klasse aktualisiert!");
            }

        }
        catch (SQLiteException e)
        {
            MessageBox.Show(e.ToString());
        }

    }

在处理数据的代码块中,您将找到AcceptChanges() 方法。此时,我的数据表可能没有出现其他更改 - 因此在应用启动后,删除一行可能是用户的第一个操作。

另外:我的数据集中的每个条目都是唯一的(标有唯一班级名称的学校班级)。

任何帮助将不胜感激!

问候,

阿兰

【问题讨论】:

  • 那么,myAdapter.DeleteCommand 是什么样子的?
  • @TaW - 据我所知 myAdapter.DeleteCommand = comBuild.GetDeleteCommand(true) 应该可以解决问题吗? (它在第三个代码块中,接近结尾)--> 我不确定,但是尽管有这个,我还需要一个特殊的删除命令吗?
  • 你能看看它的属性吗?你应该可以在那里看到删除 sql..
  • 我一回到我的工作站就会检查属性。我在逐步调试中检查了行属性 - 该行在那里并被标记为已删除。但是 AcceptChanges() 似乎没有效果。你能在我的代码中找到任何关键行吗?我不是 100% 确定,如果我正确地得到了整个更新数据表的东西......谢谢你坚持下去!
  • 它认为 Acceptchange 更多的是用于输入新数据。您可以查看 myAdapter.DeleteCommand 属性以查看其 sql。至少对于 sqlDataadapter..

标签: c# sqlite


【解决方案1】:

好的 - 所以我成功了(终于)。调试显示没有问题,除了 AcceptChanges(),它接到了一个电话,但没有导致实际删除 dataRow。

我现在能想到的只是我的主要方法是问题的一部分:我直接从数据库中获取我的 DataTable,对其进行所有操作,然后通过 Update 将其发送回 DB(请参阅我上面的更新方法)。 SQLite CommandBuilder 似乎无法解释我当时标记为“已删除”的 DAtaRow,但在不引发异常的情况下将其添加到方法的末尾。

通过这样做,我尝试了 GetChanges 方法:

 DataRow[] dr = killTable.Select("" + cmVariables.ClassName + " = '" + cmbClasses.Text + "'");

            string indexName = (killTable.Rows.IndexOf(dr[0])).ToString();

            int i = Int32.Parse(indexName);

            killTable.Rows[i].Delete();

            DataTable killItTable = killTable.GetChanges(DataRowState.Deleted);

            killClass_Execution(killItTable, cmbClasses.Text, ShortClassNm);

现在它正在工作 - killTable 的副本(killItTable - 我知道,但我明天早上做的第一件事就是给它起更好的名字 :) )为似乎被它识别的 sql commandbuilder 提供了信息。 不管它是什么 - 它现在可以工作了。

我认为这不应该发生 - 如果有人能就如何改进我的方法提出任何好的建议,我会很高兴。 最好的问候

【讨论】:

    猜你喜欢
    • 2018-11-09
    • 2018-05-07
    • 1970-01-01
    • 2021-08-18
    • 2020-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多