0

我有 DataGridView,我在其中显示从数据库读取的数据:

DataSet ds = new DataSet();
sqlDa.Fill(ds);
dgView.DataSource = ds.Tables[0]

在 UI 中添加所有行后,我需要对以前从数据库读取的行进行 SQL UPDATE,并通过单击 Save 按钮对新行执行 INSERT(添加时我不会一一保存行,只是所有当我单击“保存”按钮时它们):

foreach (DataGridViewRow dgvRow in dgView.Rows)
{
  // do insert for new rows, and update for existing ones from database
}

我如何知道哪些行是新添加的,哪些不是?我可以为从数据库读取的每一行添加某种类型的属性,以便我知道它们需要更新吗?

4

1 回答 1

0

我如何知道哪些行是新添加的,哪些不是?

你不需要;DGV 显示的数据表已经在跟踪这一点。如果您制作 SqlDataAdapter 并将SqlCommandBuilder 插入其中, 请参阅文档中的示例代码,以便它在其 InsertCommand/UpdateCommand/DeleteCommand 属性中获得查询(或者您可以将这些命令放入自己,但考虑到这一点并没有多大意义命令生成器可以自动生成它们)然后您只需说:

theDataAdapter.Update(theDataTable);

如果您没有将其保存在其他任何地方,您可以从 DGV 的 DataSource 中获取它:

theDataAdapter.Update(dgView.DataSource as DataTable);

顺便说一句,这里的“更新”一词与更新查询无关;Microsoft 应该将其称为 SaveChanges。它运行各种修改查询 (I/U/D) 而不仅仅是 UPDATE


如果你真的想知道,并且有重新发明这个轮子的强烈愿望,你可以检查 DataRow 的 RowState 属性,它会告诉你它是添加、修改还是删除,所以你可以触发适当的查询(但真的是你d 重新实现 SqlDataAdapter 已经内置的功能)


综上所述,您可能没有意识到您可以通过以下方式大大简化您的生活:

  • 将新的 DataSet 类型的文件添加到您的项目中(就像您添加一个类一样)。打开它
  • 右键单击它的表面,选择添加 TableAdapter
  • (一次)设计您的连接字符串
  • 将您的查询输入为“产生行的选择”,例如SELECT * FROM SomeTable WHERE ID = Id(建议使用在 ID 上选择的 where 子句;您可以稍后添加更多查询以执行其他操作,例如,SELECT * FROM SomeTable WHERE SomeColumn LIKE @someValue但现在选择 ID 为您提供了一个基本查询使用方便加载相关数据)。如果需要,您还可以使用现有的或新的存储过程
  • 给它一个合理的名称对,例如 FillById、GetDataById - FillBy 填充现有表,Get 获取新表
  • 结束

现在,您的代码中将有可用的对象,这些对象是包装器数据适配器和数据表 - 功能相同,但强类型更好

例如,您可以使用以下内容填充您的网格:

var ta = new SomeTableAdapter();
dgView.DataSource = ta.GetDataByFirstName("John%"); //does select * from table where firstname like 'john%' into a datatable

数据表是强类型的,所以你不能像这样访问它们:

//no
foreach(DataRow row in someTable.Rows){
  if((row["someColumn"] as string) == "hello" && row.IsNull("otherColumn"))
    row["otherColumn"] = "goodbye";
}

您已命名属性:

//yes
foreach(var row in someTable){
  if((row.SomeColumn == "hello" && row.IsOtherColumnNull())
    row.OtherColumn = "goodbye";
}

好多了。LINQ 也适用于它们,无需 AsEnumerable 或 Cast 并且无休止地转换值。

这不是魔术。VS 在幕后为您编写大量代码 - 检查 YourDataSet.Designer.cs 文件 - 数百个完全参数化的 SqlCommand,用于所有表操作(选择/插入/更新/删除),所有基础都无需键入 SELECT 命令进入工具窗格。即使这么多年过去了,它真的很好用。

哦,但是设计器在网络核心中工作得不是很好。他们在修复 netcore 带来的错误方面确实落后(其他优先事项)

于 2021-12-26T21:50:12.893 回答