C# 如何在使用SP进行更新后刷新记录

C# 如何在使用SP进行更新后刷新记录,c#,data-binding,insert,C#,Data Binding,Insert,我正在处理以下问题: 我使用MSSQL存储过程在DataGridView中显示数据。Update和Insert命令可以工作,但有一个问题: 插入新行时,自动编号的主键不会发送回我的DataAdapter。因此,在数据库中插入成功,但在DataGridView中PK保留为空。 我尝试了一些代码,如: private void _rowUpdated(object sender, SqlRowUpdatedEventArgs e) { if (e.Status ==

我正在处理以下问题: 我使用MSSQL存储过程在DataGridView中显示数据。Update和Insert命令可以工作,但有一个问题:

插入新行时,自动编号的主键不会发送回我的DataAdapter。因此,在数据库中插入成功,但在DataGridView中PK保留为空。 我尝试了一些代码,如:

    private void _rowUpdated(object sender, SqlRowUpdatedEventArgs e)
    {
        if (e.Status == UpdateStatus.Continue && e.StatementType == StatementType.Insert)
        {
            cmd = conn.CreateCommand();
            cmd.CommandText = "SELECT @@IDENTITY FROM " + e.Row.Table.TableName;

            DataRow r = dt.Rows[dt.Rows.Count - 1];
            r.ItemArray[0] = cmd.ExecuteScalar();
            //r.SetModified(); --> err?
            r.AcceptChanges();
        }
    }
在DataAdapter上,但似乎什么都不起作用。所有SQL命令都可以正常工作

当我在DataGridView中刷新数据时,一切都很完美。但问题是,排序顺序和列宽会被调整。这不是我想要的

有人能帮我解决这个问题吗

期待解决方案


谢谢

由于与sql server的连接已终止,因此@@identity将变为null,因此您将获得null值

这里不能使用scope_identity(),因为它的作用域仅限于调用它的地方,即过程

ident_current()始终返回指定表的最后一个标识值。 在复制的情况下,它可能无法正常工作

Update your commandText to ="Select ident_current("+e.Row.Table.TableName+")"
下面是使用各种检索标识值技术的结果。 将dbo.M_PatientEntry替换为表名

select ident_current('dbo.M_PatientEntry')
---------------------------------------
13

select @@identity from dbo.M_PatientEntry    
---------------------------------------
NULL
NULL

select scope_identity()    
---------------------------------------
NULL

select scope_identity() from dbo.M_PatientEntry    
---------------------------------------
NULL
NULL
另外,请尽量避免使用@Identity,而不要使用scope\u Identity()或ident\u current @@如果在正在进行插入的同一个表上使用触发器,identity将为您提供触发器表结果的递增值


由于与sql server的连接已终止,因此@@identity将变为null,因此您将获得null值

这里不能使用scope_identity(),因为它的作用域仅限于调用它的地方,即过程

ident_current()始终返回指定表的最后一个标识值。 在复制的情况下,它可能无法正常工作

Update your commandText to ="Select ident_current("+e.Row.Table.TableName+")"
下面是使用各种检索标识值技术的结果。 将dbo.M_PatientEntry替换为表名

select ident_current('dbo.M_PatientEntry')
---------------------------------------
13

select @@identity from dbo.M_PatientEntry    
---------------------------------------
NULL
NULL

select scope_identity()    
---------------------------------------
NULL

select scope_identity() from dbo.M_PatientEntry    
---------------------------------------
NULL
NULL
另外,请尽量避免使用@Identity,而不要使用scope\u Identity()或ident\u current @@如果在正在进行插入的同一个表上使用触发器,identity将为您提供触发器表结果的递增值


终于找到了答案并想与大家分享:

dt.RowChanged += new DataRowChangeEventHandler(_update_fields);


    private void _update_fields(object sender, DataRowChangeEventArgs e)
    {
        try
        {
            if (e.Action == DataRowAction.Add)
            {
                conn.Open();
                cmd = conn.CreateCommand();
                cmd.CommandText = "SELECT IDENT_CURRENT('" + e.Row.Table.TableName + "')";
                dt.Rows[dt.Rows.Count - 1][0] = int.Parse(cmd.ExecuteScalar().ToString()) + 1;
                dt.AcceptChanges();
                conn.Close();
            }
            adapt.Update(dt);
        }
        catch (SqlException ex)
        {
            Debug.WriteLine(ex.Message);
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
        }
    }
希望它能为您节省一些时间!:)

Gr
VeeWee终于找到了答案并想与大家分享:

dt.RowChanged += new DataRowChangeEventHandler(_update_fields);


    private void _update_fields(object sender, DataRowChangeEventArgs e)
    {
        try
        {
            if (e.Action == DataRowAction.Add)
            {
                conn.Open();
                cmd = conn.CreateCommand();
                cmd.CommandText = "SELECT IDENT_CURRENT('" + e.Row.Table.TableName + "')";
                dt.Rows[dt.Rows.Count - 1][0] = int.Parse(cmd.ExecuteScalar().ToString()) + 1;
                dt.AcceptChanges();
                conn.Close();
            }
            adapt.Update(dt);
        }
        catch (SqlException ex)
        {
            Debug.WriteLine(ex.Message);
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.Message);
        }
    }
希望它能为您节省一些时间!:)

Gr
VeeWee

您好,我测试了如下代码:cmd.CommandText=“SELECT IDENT_CURRENT(“”+e.Row.Table.TableName+”);var res=cmd.ExecuteScalar();Debug.WriteLine(“结果:+res”);它给出了与我的查询相同的结果。但是你是对的,最好使用这个sql函数。但问题仍然存在:PK字段为空。我猜datarow没有保存在函数中。但我使用的所有操作(更新、接受更改等)都会导致无限循环。有什么建议吗?@VeeWee:为什么不在cmd.ExecuteScalar()上设置一个断点并检查它给出的值。尝试在VS.Net中的即时窗口(Alt+Ctrl+I)上检查其结果。只需复制粘贴此
cmd.ExecuteScalar()
,然后检查您得到了什么。在sql server上尝试相同的查询。它会给你想要的结果。关于如何处理断开连接的体系结构,我不能说太多,因此也不能在与之相关的问题上给您提供太多帮助。@VeeWee:此事件行_updated()是否在循环下运行?这意味着什么“我使用的所有操作(更新、接受更改等)都会导致无限循环”事实上,我应该使用断点。该函数的结果是良好的。当我仔细观察时,我看到选择了确切的行,但是第一列没有填充查询结果。而是有一个System.DBNull值。行好像被阻塞了?我想我不能仅仅更改insertCommand,因为我想为多个表创建一个组件,所以PK的名称未知。我不认为它是在循环中运行的。至少我没有把它放在一个循环中。。。当我尝试以下内容时:dt.AcceptChanges或adapt.Update();程序开始添加行,直到出现无限循环错误。您好,我对代码进行了如下测试:cmd.CommandText=“SELECT IDENT_CURRENT(“+e.Row.Table.TableName+”)”;var res=cmd.ExecuteScalar();Debug.WriteLine(“结果:+res”);它给出了与我的查询相同的结果。但是你是对的,最好使用这个sql函数。但问题仍然存在:PK字段为空。我猜datarow没有保存在函数中。但我使用的所有操作(更新、接受更改等)都会导致无限循环。有什么建议吗?@VeeWee:为什么不在cmd.ExecuteScalar()上设置一个断点并检查它给出的值。尝试在VS.Net中的即时窗口(Alt+Ctrl+I)上检查其结果。只需复制粘贴此
cmd.ExecuteScalar()
,然后检查您得到了什么。在sql server上尝试相同的查询。它会给你想要的结果。关于如何处理断开连接的体系结构,我不能说太多,因此也不能在与之相关的问题上给您提供太多帮助。@VeeWee:此事件行_updated()是否在循环下运行?这意味着什么“我使用的所有操作(更新、接受更改等)都会导致无限循环”事实上,我应该使用断点。该函数的结果是良好的。当我仔细观察时,我看到选择了确切的行,但是第一列没有填充查询结果。而是有一个System.DBNull值。行好像被阻塞了?我想我不能仅仅更改insertCommand,因为我想为多个表创建一个组件,所以PK的名称未知。我不认为它是在循环中运行的。至少我没有把它放在一个循环中。。。当我尝试以下内容时:dt.AcceptChanges或adapt.Update();程序开始添加行,直到出现无限循环错误。