Postgres数据库包含产品表,自然主键:
create table product
(
productcode char(10) primary key,
price numeric(12,2),
... a lot of other columns
);
和其他具有自然主键的类似表
ASP。使用。NET 5 MVC应用程序,使用EF Core进行更新Npgsql数据提供程序。
如果产品代码也改变了,EF Core抛出错误
属性"Product"。Productcode'是密钥的一部分,因此不能修改或标记为已修改。要使用标识外键更改现有实体的主体,首先删除依赖项并调用'SaveChanges',然后将依赖项与新主体关联。
产品代码在其他表中用作外键(带有ON UPDATE CASCADE子句),因此无法删除。
数据库结构更改不是一个选项。
如何允许主键列的更新?
的一些想法:
在EF Core中阻止此检查,例如在更新之前强制设置旧值与新值相同
在保存更改前将主键设置为其他值
强制EF Core创建update语句并手动执行
使用一些EF Core扩展或其他框架
修改Npgsql EF core provider以允许此操作
在不改变数据库结构的情况下实现这个最好的方法是什么?
异常抛出在
行https://github.com/dotnet/efcore/blob/f62cf1b1fa45d6026e8f98113d6d6712d81094c3/src/EFCore/ChangeTracking/Internal/ChangeDetector.cs L107
private static void ThrowIfKeyChanged(InternalEntityEntry entry, IProperty property)
{
if (property.IsKey()
&& property.GetAfterSaveBehavior() == PropertySaveBehavior.Throw)
{
throw new InvalidOperationException(CoreStrings.KeyReadOnly(property.Name, entry.EntityType.DisplayName()));
}
}
是否可以将此注释掉并编译新的EF Core dll
由于您正在更改主键,因此实际上它不是更新,而是添加新产品。所以
-
从现有产品创建新产品,该产品将具有新的产品代码
-
更新所有表中具有先前产品代码的所有项,用新的外键替换先前的外键。
-
在此之后,您可以删除之前的产品。
如果您尝试关闭验证并更改代码,在此之后您的数据库将被破坏,并且您将无法再次使用它,因为您将不断地遇到集成错误。