云数据库必须显式设置sslmode=require,否则因默认prefer导致28000错误;连接字符串须含Port、Timeout=30;参数名用冒号:name且大小写敏感;大字段应流式处理;连接池Pooling=true不可关闭。

直接用 Npgsql,别碰 ODBC 或 System.Data.Odbc —— 它们在 .NET 6+ 上不维护、不支持 sslmode=require,连错都不报清楚。
连接字符串漏 sslmode 就连不上云数据库
AWS RDS、Supabase、Azure PostgreSQL 等云服务默认强制 SSL,但 Npgsql 不设 sslmode 时默认行为是 prefer,结果常报 28000: no pg_hba.conf entry 这种误导性错误。
- 云环境必须显式写
sslmode=require;本地开发且 PostgreSQL 未开 SSL 时,才用sslmode=disable(上线前务必改回) - 别省略
Port:Docker 映射、Azure Flexible Server 常用非标端口(如6432),不写就直连失败 - 密码缺失或超时未设也会静默卡住:
Timeout=30是合理底线,否则等 15 秒才抛异常 - 示例正确写法:
Host=mydb.postgres.azure.com;Port=5432;Database=appdb;Username=appuser;Password=xxx;sslmode=require;Timeout=30
NpgsqlCommand 参数名必须用冒号 :,不是 @
PostgreSQL 原生用 :name 占位符,Npgsql 虽兼容 @name 写法,但底层只认 :name 绑定。写成 @id 看似不报错,实际参数值全为 NULL。
- SQL 中写
:email,代码里也必须用":email"(注意引号和冒号) - 大小写敏感:
":Email"≠":email",不匹配也不报错,查不到数据 -
AddWithValue类型推断可能出错(比如传null被当int),建议用Add显式指定类型:cmd.Parameters.Add(":age", NpgsqlDbType.Integer).Value = 25; - 错误示范:
"WHERE id = @id"+AddWithValue("@id", 123)→ 参数不绑定
读大字段(jsonb、bytea)别一次性加载
jsonb 默认读成 string,bytea 默认转 byte[],但超过 1MB 就容易触发 OOM。流式处理才是正解。
- 读
jsonb:先ExecuteScalar()拿string,再用System.Text.Json.JsonSerializer.Deserialize<t>()</t>解析 - 读大
bytea:用GetStream(0),而不是GetValue(0);reader必须在连接活着时用,using块外访问会抛InvalidOperationException: The connection was closed - 别手动关连接再读流——
CommandBehavior.CloseConnection已过时,NpgsqlDataReader依赖连接生命周期
连接池默认开启,别关,也别以为它可有可无
Pooling=true 是默认值,且不可关闭(设 false 会忽略)。高频请求下关闭连接池会导致连接数爆炸、TCP 耗尽、响应延迟陡增。
- 连接池不是“可选优化”,而是生产环境的基础设施级保障
- 连接字符串里漏掉
sslmode比漏掉Pooling更危险——前者直接连不上,后者只是性能崩掉 - 验证是否生效:查
pg_stat_activity,活跃连接数远小于并发请求数,说明池在起作用
最容易被跳过的其实是 sslmode 和参数命名风格——它们不出现在编译期检查里,错误只在运行时悄悄发生,且现象模糊(连不上 / 查不到 / 插不进),排查成本远高于写对那一刻。



















