使用 EF-Core for PostgresSQL,我有一个具有
byte
类型字段的实体,但决定将其更改为 byte[]
类型。但是当我进行迁移时,在应用生成的迁移文件时,它引发了以下异常:
Npgsql.PostgresException (0x80004005): 42804: 列“Logo”不能 自动转换为 bytea 类型
我在互联网上搜索了解决方案,但我看到的都是其他数据类型的类似问题,而不是字节数组。请帮忙。
该错误准确地说明了正在发生的情况...在某些情况下,PostgreSQL 允许更改列类型(例如
int
-> bigint
),但在许多情况下,这种更改非常重要或具有潜在的破坏性,它会拒绝自动执行此操作。在这种特定情况下,发生这种情况是因为 Npgsql 将 CLR 字节字段映射为 PostgreSQL smallint
(2 字节字段),因为 PostgreSQL 缺少 1 字节数据字段。所以 PostgreSQL 拒绝从 smallint
转换为 bytea
,这是有道理的。
但是,您仍然可以通过自己编写数据转换来进行迁移,从
smallint
到 bytea
。为此,请编辑生成的迁移,找到 ALTER COLUMN ... ALTER TYPE
语句并添加 USING
子句。 正如 PostgreSQL 文档所说,这允许您根据现有列(甚至其他列)为该列提供新值。特别是将 int (或smallint)转换为 bytea,请使用以下命令:
ALTER TABLE tab ALTER COLUMN col TYPE BYTEA USING set_bytea(E'0', 0, col);
如果您现有的列碰巧包含多个字节(对您来说不应该是问题),它应该被截断。显然要仔细测试由此得出的数据。
虽然@Shay Rojansky给出的答案是正确的,但我在尝试如上所述应用它时遇到了一些困难。我必须对其进行一些调整才能使其适合我:
假设我们有一个这样的实体:
public class Service
{
public long Id { get; set; }
public string? Name { get; set; }
public byte? Image { get; set; }
}
您决定将“Image”的类型从“byte”更改为“byte[]”,并在更改后创建迁移。 PostgreSQL 会抛出异常,指出“列无法自动转换为 bytea 类型”
正如 @Shay Rojansky 已经指出的那样,您应该浏览迁移文件以查找类似以下内容的内容:
migrationBuilder.AlterColumn<byte[]>(
name: "Image",
table: "Services",
type: "bytea",
nullable: true,
oldClrType: typeof(string),
oldType: "text");
如果找到它,则需要将其替换为:
migrationBuilder.Sql(@"ALTER TABLE ""Services"" ALTER COLUMN ""Image"" TYPE BYTEA USING ""Image""::bytea");