使用Npgsql将C# byte[]转PostgreSQL bytea及插入报错解决
解决C# byte[]转PostgreSQL bytea插入报错问题
错误根源分析
你遇到的Parameter 'name' must have either its NpgsqlDbType or its DataTypeName or its Value set错误,本质是SQL语句参数处理错误和参数绑定不完整导致的:
- SQL中错误地将
@passwordhash用单引号包裹(E'@passwordhash'),使它被当作字符串字面量而非参数,导致Npgsql参数解析混乱。 - 遗漏了
@passwordsalt参数的绑定,SQL语句中用到该参数但代码未添加。 - 不必要地使用
encode和::bytea手动转换,Npgsql原生支持byte[]到bytea的映射。 status字段类型不匹配:SQL用0::bit但模型中是int类型,可能引发额外类型错误。
修正后的代码
1. 修正Insert方法
public static int Insert(User user) { // 简化SQL,直接使用参数,无需手动转换bytea string sqlcommand = $"INSERT INTO \"{Settings.UserTable}\" (userName, surname, email, passwordhash, passwordsalt, status) VALUES (@name, @surname, @email, @passwordhash, @passwordsalt, 0)"; using (NpgsqlCommand command = new NpgsqlCommand(sqlcommand, DatabaseConnection.Connection)) { command.Parameters.AddWithValue("name", user.Name); command.Parameters.AddWithValue("surname", user.Surname); command.Parameters.AddWithValue("email", user.Email); command.Parameters.AddWithValue("passwordhash", user.PasswordHash); // 补充passwordsalt参数绑定 command.Parameters.AddWithValue("passwordsalt", user.PasswordSalt); int result = (int)command.ExecuteNonQuery(); return result; } }
2. 可选:修正status字段类型匹配
如果数据库中status字段是bit类型,将User模型中的status改为bool类型;如果是int类型,保持SQL中的0即可,无需::bit转换。
关键说明
- Npgsql会自动处理C#
byte[]与PostgreSQLbytea的类型映射,不需要手动调用encode或添加类型转换语法。 - 所有SQL中用到的参数必须在代码中通过
AddWithValue完成绑定,避免参数不匹配。 - 禁止将参数名用单引号包裹,否则会被解析为字符串字面量,失去参数化查询的作用。
内容的提问来源于stack exchange,提问作者Josh Jennings
相关产品推荐
相关产品推荐

