如何生成 sql 命令以使用其他列更新主键

How to generate sql command to update primary key with other columns

Postgres 数据库包含具有自然主键的产品 table:

create table product 
(
    productcode char(10) primary key,
    price numeric(12,2),
    ... a lot of other columns
);

和其他具有自然主键的类似 table。

ASP.NET 5 MVC 应用程序用于使用 EF Core 更新它 Npgsql 数据提供者。

如果产品代码也被更改,EF Core 会抛出错误

The property 'Product.Productcode' is part of a key and so cannot be modified or marked as modified. To change the principal of an existing entity with an identifying foreign key, first delete the dependent and invoke 'SaveChanges', and then associate the dependent with the new principal.

产品代码在其他 table 中用作外键(带有 ON UPDATE CASCADE 子句),因此无法删除。

数据库结构更改不是一个选项。

如何也允许更新主键列?

一些想法:

  1. 在 EF Core 中阻止此检查,e.q 更新前强制将旧值设置为与新值相同。

  2. 在保存更改之前将主键设置为其他值。

  3. 强制EF Core创建更新语句并手动执行

  4. 使用一些 EF Core 扩展或其他框架。

  5. 更改 Npgsql EF 核心提供程序以允许此操作。

在不更改数据库结构的情况下,哪种方法最好?

行中抛出异常

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。

既然你是改主键,其实不是更新,而是新增产品。所以

  1. 从现有产品创建新产品,该产品将具有新产品代码

  2. 更新所有表中具有以前产品代码的所有项目,用新的外键替换以前的外键。

  3. 之后您可以删除之前的产品。

如果您尝试关闭验证并更改代码,此后您的数据库将被破坏,并且您将无法再次使用它,因为您将不断出现集成错误。