【问题标题】:Identify and update SQL record from datagrid从数据网格中识别和更新 SQL 记录
【发布时间】:2014-03-21 01:01:17
【问题描述】:

我在 C# Visual Studio 2012 中有一个简单的应用程序,其中包含一个显示 SQL 表中记录的数据网格。 我已经添加了文本框和组合框来添加新记录,效果很好。

我想要做的是直接在数据网格中更新现有记录。我有更新查询的按钮,但我有一个问题。如何识别网格中被修改的记录?

免得说网格显示

ID   Name     Age  Gender
---- -------- ---- --------
1    Steven   21   M
2    Dan      34   M

此数据显示使用

SELECT * FROM table.

我进入网格并将第二条记录的年龄从 43 修改为 36。 为了保存它,我需要运行一个更新查询,但我怎么知道被修改的 ID 是 2?有什么办法我可以做到这一点?还是其他方式?

编辑:

更新数据网格的工作方式如下:

SqlConnection con = new SqlConnection("user id=testuser12;" +
                                      "password=Reporting11#;Data Source=SERVER;" +
                                   // "Trusted_Connection=yes;" +
                                      "Initial Catalog=Partner_database; " +
                                      "connection timeout=30");
SqlCommand command = new SqlCommand("select * from [dbo].[Test_table]", con)
SqlDataAdapter sda = new SqlDataAdapter(command);
DataSet set = new DataSet("cucu");
sda.Fill(set,"cucu");
dataGridView1.DataSource = set;
dataGridView1.DataMember = "cucu";

我现在正在测试看看如何做 DataSet.AcceptChanges();部分,因为如果我使用按钮,我该如何调用数据集?因为数据集在代码的另一部分。

EDIT2:我试图将其写入答案,但我的答案被删除,没有任何解释,所以我不得不在这里进行另一次编辑。

我已经尝试过你说的,但它似乎不起作用。我有显示数据的数据网格,但是当我修改现有报告并单击保存时出现错误:“当传递带有修改行的 DataRow 集合时,更新需要有效的 UpdateCommand。”

保存按钮代码为:

private void test_tableBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
    this.Validate();
    this.test_tableBindingSource.EndEdit();
    this.tableAdapterManager.UpdateAll(this.partner_databaseDataSet);

}

而fillby函数是:

 private void fillByToolStripButton_Click(object sender, EventArgs e)
{
    try
    {
        this.test_tableTableAdapter.FillBy(this.partner_databaseDataSet.Test_table, valueToolStripTextBox.Text);
    }
    catch (System.Exception ex)
    {
        System.Windows.Forms.MessageBox.Show(ex.Message);
    }

}

保存时错误显示在以下行:

this.tableAdapterManager.UpdateAll(this.partner_databaseDataSet);

我需要修改保存按钮的作用吗?没有“.AcceptChanges”。

【问题讨论】:

  • 你试过这个 DataGridView.CellValueChanged 事件了吗?
  • 不,我没有。将搜索此并尝试。

标签: c# sql-server visual-studio-2012


【解决方案1】:

我留下了另一个答案以供简短参考。请先按照示例项目的“教程”进行操作,以便全面了解它是什么以及如何使用它。这在某些地方可能听起来有点基本,但对于使用 SO 的其他人来说是件好事。

1) 创建一个新的 WinFom 应用程序

在 Visual Studio 上,单击 FILE -> New -> Project。选择Windows Forms Application,为其命名或保留默认值并点击OK

2) 添加数据库连接

单击VIEW -> Server Explorer 菜单或简单地使用Ctrl+W,L 键盘组合。 (即按住 Ctrl 并按 W 然后按 L

在打开的面板上,单击Connect to Database 按钮。

填写必填字段,测试连接并点击OK

3) 创建数据源

单击VIEW -> Other Windows -> Data Sources 菜单或简单地使用Shift+Alt+D 键盘组合。

在打开的面板上,单击Add New Data Source 按钮。

在第一个屏幕中选择Database,在第二个屏幕中选择Dataset,然后点击Next。从下拉列表中选择您刚刚创建的数据连接,然后再次单击两次Next

在数据库对象选择屏幕中,选择要包含在数据集中的表,然后单击Finish

4) 向表单添加 DataGrid

Data Sources 面板中,单击您之前选择的对象之一并选择DataGridView

接下来,将对象名称拖放到表单中。将生成一些控件(包括数据网格)。将使用所需的连接、绑定和数据源设置数据网格。

5) 浏览代码

尝试检查生成的代码和控件属性以更好地理解解决方案。请注意表单中生成的以下代码行:

private void Form1_Load(object sender, EventArgs e)
{
  // TODO: This line of code loads data into the 'testDataSet.Language' table. You can move, or remove it, as needed.
  this.languageTableAdapter.Fill(this.testDataSet.Language);
}

private void languageBindingNavigatorSaveItem_Click(object sender, EventArgs e)
{
  this.Validate();
  this.languageBindingSource.EndEdit();
  this.tableAdapterManager.UpdateAll(this.testDataSet);

}

为对象生成了一个TableAdapter,并在加载表单时填充了来自testDataSet 的数据。

Save 按钮(小软盘图标)正在调用tableAdapterManager.UpdateAll(this.testDataSet),这将隐式调用DataSet.AcceptChanges()

请注意,您可以通过更改选择查询(通过单击上一屏幕中的Add Query)来缩小数据集的范围。

6) 创建参数化查询 - 编辑

您可以在给定数据集的海关查询中使用参数。您可以在您的情况下使用以下查询:

SELECT * FROM Table WHERE (Id = @Value)

ADO.NET 将生成一个新的FillBy() 方法,您可以使用它来代替Form_Load 方法中的常规Fill()。生成的方法将具有类似于以下内容的签名:

public virtual int FillBy(TestDataSet.TableDataTable dataTable, int Value)

请注意,输入参数的数量将根据您拥有的查询参数的数量进行扩展。类型将匹配目标数据库中字段的类型(hete int 用于 Id)

@Value 对 SQL Server 有效。如果您使用其他 DBMS,请改用 ?

SELECT * FROM Table WHERE (Id = ?)

【讨论】:

  • 谢谢你。但是我在数据网格中显示的数据被过滤了。如果您查看我的代码,则 SELECT 查询很简单,但我从表中选择 *,其中列等于文本框中的变量。我不确定我是否正确解释了这一点。因此,我显示了 SQL 表中名称为“Dan”的所有记录。在这些记录中,我想更改数据网格中的一些信息,然后保存。我不确定我是否可以使用文本框中的变量来过滤您上面给出的示例中显示的数据。希望我能清楚地解释这一点。
  • 请检查编辑,是否回答了您的问题?
  • 试试这个。非常感谢您的参与。一旦我开始工作,我会标记回复:)
  • 我是否需要创建一个刷新按钮来在我更改参数时更新网格?例如,我显示名称为 Dan 的记录,然后在文本框中将名称更改为 Julie。
  • 是的,你需要一种方法来再次执行FillBy() 方法,很可能是一个按钮
【解决方案2】:

我设法解决了这个声明公共变量的问题:

    private string variabila;
    private int varsta;
    private DataSet set = new DataSet("cucu");
    private SqlDataAdapter sda;
    private SqlCommandBuilder cmdBuilder;

并使用SQLCommandBuilder 进行更新:

    private void button1_Click(object sender, EventArgs e)
{
    SqlConnection con = new SqlConnection("Data Source=SERVER;" +
                                          "Initial Catalog=Partner_database;" +
                                          "Integrated Security=True");
    SqlCommand command = new SqlCommand("select * from [dbo].[Test_table]", con);

    sda = new SqlDataAdapter(command);
    sda.AcceptChangesDuringFill = true;
    sda.AcceptChangesDuringUpdate = true;
    set.Clear(); //just to make sure i have a clear set
    cmdBuilder = new SqlCommandBuilder(sda); //use the command builder to create the commands
    sda.Fill(set_date,"cucu1");
    dataGridView1.DataSource = set_date;
    dataGridView1.DataMember = "cucu1";
}

并将更新的记录保存到数据库中:

private void button4_Click(object sender, EventArgs e)
{
      sda.Update(set.Tables["cucu"]);
}

如果没有命令生成器,Update 命令将无法工作。

【讨论】:

    【解决方案3】:

    如果您还没有使用DataSet,您可能应该考虑使用它。您可以在 DataGrid 中将 DataSet 定义为数据源,并定义您需要运行的查询以显示所需的数据。

    在您进行更改后,只需致电DataSet.AcceptChanges() 即可解决您所询问的所有问题。

    这里有一些关于如何使用 DataSet 的有用文档:

    【讨论】:

    • 谢谢。我正在尝试使用数据集在网格中获取我的数据,但它什么也没显示。我无法在此处添加代码,我该怎么做?我会回答我自己的问题吗?
    • 我已经编辑了我最初的问题。我添加了 EDIT 下的内容:。
    • 我会给你一个样本,我现在正在写它
    猜你喜欢
    • 2014-06-08
    • 1970-01-01
    • 1970-01-01
    • 2016-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-01
    • 1970-01-01
    相关资源
    最近更新 更多