PostgreSQL创建表后未生成同名复合类型,C#映射失败求助
PostgreSQL表对应复合类型无法找到的排查方案
以下是几个你可能遗漏的关键点:
模式(Schema)未指定
PostgreSQL的表和对应的复合类型默认归属public模式,但如果你的表建在自定义模式下,复合类型也会在该模式中。- 命令行查询时需指定模式,比如:
SELECT n.nspname AS schema, t.typname AS type_name FROM pg_type t JOIN pg_namespace n ON t.typnamespace = n.oid WHERE t.typtype = 'c' AND t.typrelid = (SELECT oid FROM pg_class WHERE relname = 'mytable'); - PGAdmin中要切换到对应模式的「复合类型」节点查看,而非默认的public模式。
- C#映射时需带上模式名,比如:
this.connection.TypeMapper.MapComposite<MyTable>("your_schema.mytable");
- 命令行查询时需指定模式,比如:
权限不足
当前登录的数据库用户可能没有权限查看目标模式下的类型。可以切换到超级用户(如postgres)确认类型是否存在,或者给当前用户赋权:GRANT USAGE ON SCHEMA your_schema TO your_db_user;表名大小写敏感问题
如果建表时使用了双引号(比如CREATE TABLE "MyTable" (...)),复合类型的名字会保留大小写,查询和映射时必须严格匹配:- SQL查询:
SELECT typname FROM pg_type WHERE typname = 'MyTable'; - C#映射:
this.connection.TypeMapper.MapComposite<MyTable>("\"MyTable\"");
- SQL查询:
系统表查询方式错误
直接查询pg_type系统表时,要过滤复合类型的标识:typtype = 'c'(c代表复合类型),同时关联表的oid来精准定位。Npgsql映射时机或版本问题
- 确保Npgsql版本是较新的,旧版本对复合类型的支持可能有缺陷。
- 必须在数据库连接打开后执行
TypeMapper.MapComposite操作,否则无法读取数据库元数据。 - 可以先通过代码查询所有复合类型,确认目标类型是否存在:
using var cmd = new NpgsqlCommand( "SELECT nspname || '.' || typname FROM pg_type WHERE typtype = 'c'", this.connection); var allComposites = cmd.ExecuteReader() .Cast<IDataRecord>() .Select(r => r.GetString(0)) .ToList(); // 检查allComposites中是否包含你的目标类型
内容的提问来源于stack exchange,提问作者YoSh
相关产品推荐
相关产品推荐

