首页 > 解决方案 > EF Core 迁移现有数据

问题描述

我正在尝试在迁移期间重新定位我的 postgresql 数据库中的信息。存储在一个表中的数据被分成多个表,表中通过外键链接它们。

旧表:itemsInBag

ID
name
baglabel

新表:item、itemsInBag、bag

item
Id
Name

itemsInBag
Id
ItemId
BagId

bag
Id
BagLabel

目前我有这些 SQL 语句来尝试将它们链接在一起。这是在添加新表和字段之后以及删除 itemsInBag 字段之前完成的。#

        migrationBuilder.Sql(
            "INSERT INTO items (Name)" +
            "SELECT (name) FROM itemsInBag");

        migrationBuilder.Sql(
            "INSERT INTO bag baglabel" +
            "SELECT DISTINCT baglabel FROM itemsInBag");

        migrationBuilder.Sql(
            "UPDATE itemsInBag SET bagid =(SELECT id FROM bag WHERE bag.baglabel = itemsInBag.baglabel)"
        );

        migrationBuilder.Sql(
            "UPDATE itemsInBag SET itemid =(SELECT id FROM items WHERE items.name = itemsInBag.name)"
        );

尝试运行迁移时收到此错误

$exception  {"23505: could not create unique index \"IX_itemsinbag_bagid_itemid\""} Npgsql.PostgresException

"Key (bagid, itemid)=(0, 0) is duplicated."

从我读过的所有内容来看,这似乎是正确的方法。有没有更好的方法来做到这一点?有什么我想念的吗?

更新:如果我将 bagid 和 itemid 上的唯一约束移到 SQL 语句之后,我会收到此错误

$exception  {"23503: insert or update on table \"itemsinbag\" violates foreign key constraint \"FK_itemsinbag_bag_bagid\""} Npgsql.PostgresException
"Key (bagid)=(0) is not present in table \"bag\"

标签: c#entity-frameworkef-core-2.1

解决方案


想出了解决这个问题的办法。这完全是安排索引和外键约束与我的 SQL 语句相关的位置的问题。重新排列表数据后,需要创建外键约束。在插入的项目表不存在之后也出现错误。需要包含架构,以便最终的 SQL 语句如下所示:

migrationBuilder.Sql(
        "INSERT INTO schema.items (Name)" +
        "SELECT name FROM schema.itemsInBag");

    migrationBuilder.Sql(
        "INSERT INTO schema.bag (baglabel)" +
        "SELECT DISTINCT baglabel FROM schema.itemsInBag");

    migrationBuilder.Sql(
        "UPDATE schema.itemsInBag SET bagid =(SELECT id FROM schema.bag WHERE schema.bag.baglabel = schema.itemsInBag.baglabel)"
    );

    migrationBuilder.Sql(
        "UPDATE schema.itemsInBag SET itemid =(SELECT id FROM schema.items WHERE schema.items.name = schema.itemsInBag.name)"
    );

推荐阅读