Master-Detail关系在ADO.NET中不插入级联

时间:2010-11-11 11:38:43

标签: ado.net ironpython

我尝试使用IronPython(在SharpDevelop 4中开发)针对SQL Server处理Winforms中新主记录和相关子记录的插入,尽管我认为这是一个普遍的ADO.NET问题。表单只有一个主记录(预订)和许多详细记录(行)。如果主记录已经存在,我可以毫无问题地插入子记录,但如果添加新的预订记录,我的关系似乎不会级联。

具体代码 - 首先我按如下方式添加我的关系:

parentColumn = self._dataSetBookings.Tables["booking"].Columns["intBookingID"]
childColumn = self._dataSetBookings.Tables["lines"].Columns["intBookingID"]
bookingRelationship = DataRelation("mediabooking",parentColumn,childColumn,True)
self._dataSetBookings.Relations.Add(bookingRelationship)
self._dataSetBookings.EnforceConstraints = True

intBookingID是预订表上的标识列

我的应用更新程序如下所示,请注意在行上添加的事件已更新。使用的sql命令实际上是'select * from intBookingID = @intBookingID)

# update booking
adapter = SqlDataAdapter()
adapter.RowUpdated += self.AdapterUpdateBooking
cmd = adapter.SelectCommand = self.conn.CreateCommand()

cmd.CommandText = self.bookingSqlCmd
parameter = cmd.Parameters.Add("@intBookingID", SqlDbType.Int)
parameter.Value = self.BookingID 

builder = System.Data.SqlClient.SqlCommandBuilder(adapter)
adapter.InsertCommand = builder.GetInsertCommand()
adapter.UpdateCommand = builder.GetUpdateCommand()
adapter.Update(self._dataSetBookings,"booking")

# update lines
adapter = SqlDataAdapter()
cmd = adapter.SelectCommand = self.conn.CreateCommand()             
cmd.CommandText = self.lineSqlCmd
parameter = cmd.Parameters.Add("@intLineBookingID", SqlDbType.Int)
parameter.Value = self.BookingID 

builder = System.Data.SqlClient.SqlCommandBuilder(adapter)
adapter.InsertCommand = builder.GetInsertCommand()
adapter.UpdateCommand = builder.GetUpdateCommand()
adapter.UpdateCommand = builder.GetDeleteCommand()      
adapter.Update(self._dataSetBookings,"lines")

最后是RowUpdated事件 - 它只针对预订行触发一次,这样我们就可以获得刚刚插入的记录的标识

    def AdapterUpdateBooking(self, sender, e):
    cmd = self.conn.CreateCommand()
    #cmd.CommandText = "SELECT SCOPE_IDENTITY()" - this does not work!
    cmd.CommandText = "SELECT @@IDENTITY "
    newBookingID = cmd.ExecuteScalar()

    if newBookingID != System.DBNull:
        for bookingRow in self._dataSetBookings.Tables["booking"].Rows:
            bookingRow["intBookingID"] = newBookingID

在应用更新时跟踪此过程,通过“SELECT @@ IDENTITY”调用检索正确的ID值以获取新记录(但SCOPE_IDENTITY返回null,我不明白,可能是一个线索?)。但是,当该值应用于主(预订)表中的intBookingID字段时,它不会在详细信息(行)表中级联更新intBookingID字段,并且插入失败。

但是,如果从数据库加载了Master(预订)记录,并添加了新行,则关系确实有效,intBookingID字段正确设置,插入成功。

我觉得我必须错过一些微不足道的事情,但我做错了什么?

1 个答案:

答案 0 :(得分:0)

您是否编码过级联?我没有看到它。试试这个。

ForeignKeyConstraint oFKey;
oFKey = new ForeignKeyConstraint("BookingForeignkey", parentColumn, childColumn);
oFKey.DeleteRule = Rule.Cascade;
oFKey.UpdateRule = Rule.Cascade;
oFKey.AcceptRejectRule = AcceptRejectRule.Cascade;
self._dataSetBookings.Tables["booking"].Constraints.Add(oFKey);
self._dataSetBookings.EnforceConstraints = True

你可能想读这个: DataTable Constraints (ADO.NET)

编辑:我不明白这部分

if newBookingID != System.DBNull:
        for bookingRow in self._dataSetBookings.Tables["booking"].Rows:
            bookingRow["intBookingID"] = newBookingID

为什么要分配所有行'newBookingID'?由此我猜测可能没有为数据集定义主键。如果是,则赋值行必定会抛出一些错误。