我的情况是,我的表包含一些数据也有主键ID,我在datagridview中显示该数据,现在我必须删除datagridview和table中的任何特定行。
现在点击部分的代码没问题,我得到了行号,我删除了表中主键ID对应的行,但是当删除一行时发生探测然后让我说我点击了第3行,然后转到表并尝试找到ID(PK)为3,并删除它, 但这不是一个好方法,因为现在表的顺序将是
1
2 //3 is deleted
4
5
因此,下次当我在数据网格视图中单击4时,它将查找ID = 3(因为行号为3),因此我的表中现在ID = 3,因此不会删除任何内容。 / p>
所以我正在寻找一种基于行号删除的方法,不是基于ID号,所以我在数据网格视图中点击哪一行,相应的行号也将在表中删除。
我根据ID删除行的代码是:
internal void DeleteIndividualParcel(string tableName, string Conx, int number)
{
//number is the row number clicked in dataGridView
NpgsqlConnection MyCnx = new NpgsqlConnection(Conx);
NpgsqlCommand MyCmd;
List<string> finalList = new List<string>();
string delete = "";
delete = "DELETE FROM " + tableName + " WHERE id =" + number + ";";
try
{
MyCnx.Open();
}
catch (Exception ex)
{
MessageBox.Show("The connection can't be opened!" + ex.Message);
}
MyCmd = new NpgsqlCommand(delete, MyCnx);
try
{
MyCmd.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show("The query can't be executed from DeleteParcel!" + ex.Message);
}
MyCnx.Close();
}
如何更改代码以使行号基础删除?
答案 0 :(得分:1)
请不要使用此解决方案。而是遵循其他答案的建议:始终将主键保留在任何CRUD操作中,因此您删除id = something的位置。
你应该总是删除坚实的标准,而不是删除表中行的位置(除非你只是清理表的一部分,这个row_number()业务非常方便)。这是为什么?在以下情况下,您可以删除您不想要的内容:
现在,由于这显然是PostgreSql,这就是你需要的:
DO $$
DECLARE vid INT;
BEGIN
SELECT tt.id into vid
from (select id, row_number() over () as rn from testtable) tt
WHERE tt.rn=2;
DELETE FROM testtable WHERE testtable.id=vid;
END $$;
删除第3行
由于第3行因您对表的排序方式而有所不同,如果组成该DataGrid的查询具有Order By
,请确保将其包含在over()
中,如下所示:
row_number() over(ORDER BY id) as rn
答案 1 :(得分:0)
处理此问题的最快,最简单和最差的方法是在每次删除后重新查询数据库并重建网格。
稍微不那么脏,但也更难的方法是从网格中删除项目时从列表中删除该项目。
另一种方法是将ID放在网格中的隐藏列中。
答案 2 :(得分:0)
基本规则:
首先,在UI和数据库表之间进行双向通信时,应该注意选择能够唯一定义记录集的表的正确列。所以,通常&#34; PK&#34;选择(主键)列。
其次,在进行任何类型的CRUD(创建,读取,更新和删除)操作时,两个侧面列表都应相应更新。
如果您使用行号作为操作数据库记录的键,则确保在每次操作后同步UI和DB中的列表。