首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DataRelation插入和ForeignKey

DataRelation插入和ForeignKey
EN

Stack Overflow用户
提问于 2009-05-08 16:43:43
回答 2查看 5.1K关注 0票数 3

我有一个winforms应用程序,它有两个DataGridViews,分别显示Person和Address表中的主-详细关系。Person表有一个自动递增主键的PersonID字段。Address有一个PersonID字段,它是FK。

我用DataAdapter填充我的DataTables,并设置Person.PersonID列的AutoIncrement=true和AutoIncrementStep=-1。我可以从DataGridView在Person DataTable中插入记录。PersonID列显示PersonID的唯一负值。我通过调用DataAdapter.Update(PersonTable)更新数据库,SQL Server自动将负的PersonID转换为正的唯一值。

这就是问题所在。Address DataGridView显示了地址表,其中包含一个DataRelation to Person by PersonID。插入的人员记录具有临时负PersonID。我现在可以通过DataGridView将记录插入到Address中,并将DataRelation映射中的Address.PersonID设置为负值。我调用Adapter.Update(AddressTable),负的PersonID进入地址表,破坏了关系。

你们是如何使用DataTables和master-detail DataGridViews来处理主键/外键的?

谢谢!史蒂夫

编辑:

经过更多的谷歌搜索,我发现SqlDataAdapter.RowUpdated事件给了我所需要的东西。我使用@@IDENTITY创建了一个新命令来查询最后插入的id。它工作得很好。DataRelation为我更新了Address.PersonID字段,因此需要先更新Person表,然后再更新Address表。使用正确的in正确插入所有新记录!

代码语言:javascript
复制
            Adapter = new SqlDataAdapter(cmd);
            Adapter.RowUpdated += (s, e) => 
            {
                if (e.StatementType != StatementType.Insert) return;
                //set the id for the inserted record
                SqlCommand c = e.Command.Connection.CreateCommand();
                c.CommandText = "select @@IDENTITY id";
                e.Row[0] = Convert.ToInt32( c.ExecuteScalar() );
            };
            Adapter.Fill(this);
            SqlCommandBuilder sb = new SqlCommandBuilder(Adapter);
            sb.GetDeleteCommand();
            sb.GetUpdateCommand();
            sb.GetInsertCommand();
            this.Columns[0].AutoIncrement = true;
            this.Columns[0].AutoIncrementSeed = -1;
            this.Columns[0].AutoIncrementStep = -1;    
EN

回答 2

Stack Overflow用户

发布于 2009-05-08 23:28:15

需要在“数据集设计器”中双击该关系,然后选择“级联更新”。当为Person表生成真实SQL server生成的PK值时,它还会自动设置address表中的外键值。

你不需要做任何RowUpdated事件的事情。它内置于数据集功能中。

票数 1
EN

Stack Overflow用户

发布于 2009-06-16 22:33:49

我也有类似的问题,但我的解决方案有点不同。

@Noel肯尼迪:您的解决方案不适用于SQL Server2005CE,因为它不支持多个语句,并且TableAdapter不会生成更新父表中的自动增量列所需的刷新代码。

注意:您仍然需要在关系中进行级联更新,以便更新子表。

我还在TableAdapter中添加了一个方法,它足够通用,只需在所有父TableAdapters中复制/粘贴即可。我唯一要更改的是标识行类型和索引(如果需要)。我还向TableAdapter添加了一个名为GetIdentity()的查询。通过使用sql="SELECT @@IDENTITY;“添加标量查询,可以将其添加到数据集设计器的标识中。

现在自定义函数是:

代码语言:javascript
复制
public int InsertAndRefresh(System.Data.DataTable dataTable)
{
    int updated = 0;

    System.Data.DataRow[] updatedRows = dataTable.Select("", "", System.Data.DataViewRowState.Added);

    bool closed = (this.Connection.State == System.Data.ConnectionState.Closed);
    if (closed) 
        this.Connection.Open();

    foreach (System.Data.DataRow row in updatedRows)
    {
        updated+=this.Adapter.Update(new global::System.Data.DataRow[] { row });
        decimal identity = (decimal)this.GetIdentity();
        row[0] = System.Decimal.ToInt64(identity);
        row.AcceptChanges();
    }
    if (closed)
        this.Connection.Close();

    return updated;
}

您想要先在父对象上调用此函数。然后像往常一样做所有事情(更新父项,然后更新子项)。

干杯!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/840757

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档