将主键修改为外键时出错
Posted
技术标签:
【中文标题】将主键修改为外键时出错【英文标题】:Error when modifying a primary key as a foreign key 【发布时间】:2021-11-23 22:20:30 【问题描述】:我在实体框架中有一个主键作为外键。
public class RailcarTrip
[Key, ForeignKey("WaybillRailcar")]
public int WaybillRailcarId get; set;
public WaybillRailcar WaybillRailcar get; set;
// Etc.
这似乎工作正常,并生成下表。
CREATE TABLE [dbo].[RailcarTrips](
[WaybillRailcarId] [int] NOT NULL,
[StartDate] [datetime2](7) NOT NULL,
[DeliveryDate] [datetime2](7) NULL,
[ReleaseDate] [datetime2](7) NULL,
[ReturnDate] [datetime2](7) NULL,
[DeliveryEta] [datetime2](7) NULL,
[ReleaseEta] [datetime2](7) NULL,
[ReturnEta] [datetime2](7) NULL,
[ReturnCity] [nvarchar](80) NULL,
[ReturnState] [nvarchar](2) NULL,
[TripType] [int] NOT NULL,
CONSTRAINT [PK_RailcarTrips] PRIMARY KEY CLUSTERED
(
[WaybillRailcarId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[RailcarTrips] WITH CHECK ADD CONSTRAINT [FK_RailcarTrips_WaybillRailcars_WaybillRailcarId] FOREIGN KEY([WaybillRailcarId])
REFERENCES [dbo].[WaybillRailcars] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[RailcarTrips] CHECK CONSTRAINT [FK_RailcarTrips_WaybillRailcars_WaybillRailcarId]
GO
但是当我尝试更改此 PK/FK 以使其引用不同的记录时出现错误。
“RailcarTrip.WaybillRailcarId”属性是键的一部分,因此不能修改或标记为已修改。要使用标识外键更改现有实体的主体,首先删除依赖项并调用“SaveChanges”,然后将依赖项与新主体关联。
我不明白为什么这是个问题?主键未设置为实体/自动设置。此代码应该是 FK 的简单更新。我不想删除任何东西。谁能解释为什么这是个问题?
这似乎是实体框架错误,而不是 SQL Server 错误。
【问题讨论】:
为什么您不添加自动增量主键而忘记这一点。否则在整个项目开发过程中你会一个接一个的出现问题。 @Serge:因为,作为 PK/FK,我需要能够将此 PK 设置为特定的行 ID。 Entity Framework 将自动使 PK 自动递增。但它在这里没有正确地做到这一点。 这将使更改 FK 的成本更低,并使 EF 能够支持该操作。 【参考方案1】:EF 不支持修改主键。因此,您需要删除并插入(Remove+SaveChanges+Add+SaveChanges)RailCarTrip 以将其移动到不同的 WaybillRailcar。或者,您可以直接在 TSQL 中更新 PK/FK。
【讨论】:
也可以通过存储过程来完成 谢谢,似乎发送原始 SQL 命令是最高效的答案。我不明白为什么 EF 会阻止这一点。我可能需要一次对任意数量的记录执行此操作。 经过仔细考虑,我明白为什么这可能不是最好的方法。也许我会修改它,以便我有一个单独的 PK 和 FK,并在 FK 上放置一个唯一的索引。【参考方案2】:如果我对您的理解正确,那就是您想要更改实体主键的值 (RailcarTrip
),而不是您已经回答了您自己的问题 - EF 通知您,主键不是可修改的值,这对于 SQL 数据库是正确的。
此键是否也是外键无关紧要。
要修改主键值,必须删除相应的条目并使用新的键值重新创建它。
【讨论】:
SQL Server(和 Azure SQL 数据库)支持更新主键,这很少是个好主意。 正如@DavidBrowne-Microsoft 所指出的,这是允许的。我不知道为什么这不是一个好主意。这似乎是一个好主意。不管怎样,我不明白为什么 EF 不允许这样做。 实体是由 PK 跟踪的,所以它会使更改跟踪复杂化。理论上这不是一个棘手的问题,但 EF 只是没有实现它。以上是关于将主键修改为外键时出错的主要内容,如果未能解决你的问题,请参考以下文章