尝试进行分层更新会导致错误“无法插入外键值”

Posted

技术标签:

【中文标题】尝试进行分层更新会导致错误“无法插入外键值”【英文标题】:Trying to do a hierarchical update results in an error "A foreign key value cannot be inserted" 【发布时间】:2011-04-12 09:59:00 【问题描述】:

我对 DAO 和 SQL Server 有点陌生,当我尝试将值插入到两个具有关系的表中时遇到了问题。表Photos 有一个gpsId 字段,它与GPSLocations 表的id 字段具有外键关系。我想创建一个链接到新 GPSLocation 的新照片条目,因此代码如下所示:

gpsRow = dataset.GPSLocations.AddGPSLocationsRow("0.0N", "3.2W");
dataset.Photos.AddPhotosRow(@"c:\path\file.jpg", gpsRow);
tableAdapterManager.UpdateAll(dataset); 

但是这会导致以下错误:

无法插入外键值 因为对应的主键 值不存在。 [外键 约束名称 = photoToGps ]

我正在使用 SQL Server CE。我的理解是否正确,TableAdapterManager 应该处理这个分层更新?我只是将这些表拖到 XSD 视图上,并依靠它自动创建的包装类。我是否需要更改关系的任何内容(例如,使其成为外键约束)?我注意到在某些情况下,gps id 是正数,有时是负数,这是否相关?

编辑: 我还确保将更新属性设置为 CASCADE,这会导致相同的错误。分层更新设置为true,设计器中两个表之间存在外键约束。

【问题讨论】:

也许我们需要更多信息。我假设 GPSLocations 表中的第三个字段是 id 字段并被标记为主键。它不是身份字段是否有原因?为什么照片没有 id 字段(这可能与您的问题无关,我只是想更多地了解架构)。 抱歉,第三个字段具有误导性,因此我已将其删除,它只是一个数据成员,而不是身份。 GPSLocations 表有一个标识列id(也是主键),它与Photos 表的gpsId 列有关系 【参考方案1】:

这只是您的数据集的配置。在 Visual Studio 的数据集设计器中双击表之间的关系,选择 Both Relation And Foreigh Key Constraint 选项并在 Update Rule 字段中选择 Cascade选项,必须是它。

有关该主题的一些信息在 MSDN 中,您可以在这里查看http://msdn.microsoft.com/en-us/library/bb629317.aspx 并转到相关主题。

【讨论】:

正如我在对 ktharsis 的回复和我的编辑中提到的,我已经启用了外键约束并且更新规则设置为级联。 你说你已经尝试了不同的选项,但我不知道你已经尝试过这个。只是“Foreigh Key Constraint”是行不通的。更新规则“级联”必须完全有“关系和外键约束”。我刚刚尝试过,它奏效了。也许那是因为您使用的是 SQL Server CE,而我使用的是 MS SQL 2008 Developer Edition。 我现在发现这是 SQL Server CE 和完整的 SQL Server 之间的区别——请参阅下面我自己的答案【参考方案2】:

我已经设法找到了这个问题的根源,这归结为与完整的 SQL Server 相比,SQL Server CE 的局限性。事实证明,出现问题的主要暗示是因为 id 为负数。在将行插入数据库之前,DataSet 中的 id 为负数,此时它被解析为正索引。它没有成为正索引的事实发生了,因为TableAdapterManager 通常会执行INSERT 的批处理语句,然后是SELECT 来更新id。但是,SQL Server CE 不支持批处理语句,因此这需要编写额外的代码,以便我们通过响应RowUpdated 事件来模拟SELECT 步骤。这个MSDN article 解释了这些步骤。

【讨论】:

有趣。我想知道在 LINQ To SQL 和实体框架中是否存在同样的问题,它们是微软自己的 DataSets 替代品。【参考方案3】:

您是否按照here 的描述启用了分层更新?

【讨论】:

【参考方案4】:

两个表之间是否存在外键约束(XSD 设计器上应该有一条线连接它们)?由于您的字段名称不同,因此当您将表格拖动到设计图面时,它可能不会自动添加。

【讨论】:

是的,有一个外键约束。我在 XSD 设计器中尝试了不同的选项来启用约束或关系。我得到了同样的结果。【参考方案5】:

由于 photoToGps(外键)列依赖于主键 (id),因此除非存在对应的 id,否则无法添加 photoToGps。因此,您需要的是单独更新,而不是执行 UpdateAll。首先更新 GPSLocations 表,然后再更新另一个表。这样,在为它添加 photoToGPS 之前,您将拥有一个 id。

【讨论】:

谢谢,但在尝试 TableAdapterManager 之前我已经尝试过了,我认为它应该处理这种更新,其中存在意味着必须首先更新一个表的关系。

以上是关于尝试进行分层更新会导致错误“无法插入外键值”的主要内容,如果未能解决你的问题,请参考以下文章

将 Json 文件中的数据加载到 PostgresSql 中会导致:错误“重复键值违反唯一约束 - 已存在。”

无法修复警告检测到重复键:“0”。这可能会导致更新错误

将数据从Json文件加载到Postgresql会导致:错误“重复键值违反唯一约束 - 已存在”。

此类与键 scrollView 的键值编码不兼容

卸载IE11发生错误,没有成功卸载全部更新?

Pytorch实现网络部分层的固定不进行回传更新