C# with Npgsql - 无法使用处理程序类型 Int32Handler 编写 CLR 类型 System.String
C# with Npgsql - Can't write CLR type System.String with handler type Int32Handler
我在尝试将整数添加到 Postgresql 数据库时遇到问题。 Varchars 工作正常,但是当我使用代码时:
var parameter = cmd.CreateParameter();
parameter.Value = Int32.Parse(x.Value.ToString());
Console.WriteLine(parameter.Value);
parameter.ParameterName = x.Key.ToString();
cmd.Parameters.Add(new NpgsqlParameter("confirmations",NpgsqlTypes.NpgsqlDbType.Integer));
for (int search=0; search != cmd.Parameters.Count; search++)
执行时出错,我正在使用:
cmd.ExecuteNonQuery();
听起来像:
Database problem: System.InvalidCastException: Can't write CLR type System.String with handler type Int32Handler\
at lambda_method(Closure , NpgsqlTypeHandler , Object , NpgsqlLengthCache& , NpgsqlParameter )
at Npgsql.NpgsqlParameter.ValidateAndGetLength() in C:\projects\npgsql\src\Npgsql\NpgsqlParameter.cs:line 553
at Npgsql.NpgsqlCommand.ValidateParameters() in C:\projects\npgsql\src\Npgsql\NpgsqlCommand.cs:line 793
at Npgsql.NpgsqlCommand.ExecuteDbDataReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken) in C:\projects\npgsql\src\Npgsql\NpgsqlCommand.cs:line 1141
at Npgsql.NpgsqlCommand.ExecuteNonQuery(Boolean async, CancellationToken cancellationToken) in C:\projects\npgsql\src\Npgsql\NpgsqlCommand.cs:line 1042
at Npgsql.NpgsqlCommand.ExecuteNonQuery() in C:\projects\npgsql\src\Npgsql\NpgsqlCommand.cs:line 1025
at BitcoinType.DatabaseManager.MakeInsert(Dictionary`2 requestData) in /Users/kamilkostrzewski/Projects/BitcoinType/BitcoinType/Program.cs:line 261
没有帮助我。
很难理解上面的代码示例 - 您创建并填充了 parameter
,但随后在评论中添加了一个完全不同的 NpgsqlParameter
实例。
但是,错误消息清楚地表明您正在尝试将字符串写为整数。当您将 NpgsqlParameter.Value
设置为字符串值,但将其 NpgsqlDbType
设置为 Integer
时,就会发生这种情况。要么完全省略设置 NpgsqlDbType
(Npgsql 通常会从值中推断出正确的类型),要么确保它们正确对齐。
假设您有以下 table:
create table foo (
bar integer
)
如果您准备插入 table 如下:
NpgsqlCommand cmd = new NpgsqlCommand("insert into foo values (:BAR)", conn);
cmd.Parameters.Add(new NpgsqlParameter("BAR", NpgsqlDbType.Integer));
很明显这会引发错误:
cmd.Parameters[0].Value = "Hello";
cmd.ExecuteNonQuery();
出于同样的原因,这会引发错误:
insert into foo values ('Hello')
这显然有效,因为它是一个整数:
cmd.Parameters[0].Value = 5;
但您可能不知道以下内容仍然有效,因为它们是兼容的数据类型:
cmd.Parameters[0].Value = 5M;
cmd.Parameters[0].Value = 5f;
cmd.Parameters[0].Value = (short)5;
cmd.Parameters[0].Value = (long)5;
然而,即使 PostgreSQL 有足够的容忍度来接受原始 SQL:
insert into foo values ('5')
Npgsql 4 将在您尝试执行此操作时抛出您提到的错误:
cmd.Parameters[0].Value = "5";
cmd.ExecuteNonQuery();
有趣的是,我很确定它与 Npgsql 一起工作 3.x,但我认为该错误是一种改进。
因为它需要一个数字数据类型,简单的解决方案是确保你分配的任何 .Value
也是一个数字数据类型,最好是一个整数:
cmd.Parameters[0].Value = Convert.ToInt32(yourObject);
cmd.ExecuteNonQuery();
关于错误捕获的标准警告和使用 int.TryParse
。
从您上面的代码来看,您实际上可能正在将可能已经作为整数存在的内容转换为字符串。如果您取消所有这些,您可能会发现它开箱即用。在任何情况下,.Value
属性 都需要是数字。
我遇到了这个问题,我是这样解决的。在我的数据库中,我有一个类型为 Integer 的列。如果要向此列添加数据,您应该使用 NpgsqlDbType.Integer 数据类型。但是当我使用 NpgsqlDbType.String 数据类型时,我得到了那个错误。
所以你应该改变你的 NpgsqlDBtType。希望对你有帮助。
我在使用以下代码时遇到了同样的问题
var utctime = DateTimeOffset.UtcNow.ToString("yyyy-MM-dd HH:mm:ss");
writer.Write(utctime, NpgsqlDbType.TimestampTz);
所以基本上您是将 utctime 转换为字符串,但在写入数据库时使用类型作为时间戳,这不是字符串。因此它会抛出错误,因为数据与数据类型不兼容。
修复方法是不要将 utctime 转换为字符串,只需按原样使用即可。所以工作解决方案是
var utctime = DateTimeOffset.UtcNow;
writer.Write(utctime, NpgsqlDbType.TimestampTz);
我在尝试将整数添加到 Postgresql 数据库时遇到问题。 Varchars 工作正常,但是当我使用代码时:
var parameter = cmd.CreateParameter();
parameter.Value = Int32.Parse(x.Value.ToString());
Console.WriteLine(parameter.Value);
parameter.ParameterName = x.Key.ToString();
cmd.Parameters.Add(new NpgsqlParameter("confirmations",NpgsqlTypes.NpgsqlDbType.Integer));
for (int search=0; search != cmd.Parameters.Count; search++)
执行时出错,我正在使用:
cmd.ExecuteNonQuery();
听起来像:
Database problem: System.InvalidCastException: Can't write CLR type System.String with handler type Int32Handler\
at lambda_method(Closure , NpgsqlTypeHandler , Object , NpgsqlLengthCache& , NpgsqlParameter )
at Npgsql.NpgsqlParameter.ValidateAndGetLength() in C:\projects\npgsql\src\Npgsql\NpgsqlParameter.cs:line 553
at Npgsql.NpgsqlCommand.ValidateParameters() in C:\projects\npgsql\src\Npgsql\NpgsqlCommand.cs:line 793
at Npgsql.NpgsqlCommand.ExecuteDbDataReader(CommandBehavior behavior, Boolean async, CancellationToken cancellationToken) in C:\projects\npgsql\src\Npgsql\NpgsqlCommand.cs:line 1141
at Npgsql.NpgsqlCommand.ExecuteNonQuery(Boolean async, CancellationToken cancellationToken) in C:\projects\npgsql\src\Npgsql\NpgsqlCommand.cs:line 1042
at Npgsql.NpgsqlCommand.ExecuteNonQuery() in C:\projects\npgsql\src\Npgsql\NpgsqlCommand.cs:line 1025
at BitcoinType.DatabaseManager.MakeInsert(Dictionary`2 requestData) in /Users/kamilkostrzewski/Projects/BitcoinType/BitcoinType/Program.cs:line 261
很难理解上面的代码示例 - 您创建并填充了 parameter
,但随后在评论中添加了一个完全不同的 NpgsqlParameter
实例。
但是,错误消息清楚地表明您正在尝试将字符串写为整数。当您将 NpgsqlParameter.Value
设置为字符串值,但将其 NpgsqlDbType
设置为 Integer
时,就会发生这种情况。要么完全省略设置 NpgsqlDbType
(Npgsql 通常会从值中推断出正确的类型),要么确保它们正确对齐。
假设您有以下 table:
create table foo (
bar integer
)
如果您准备插入 table 如下:
NpgsqlCommand cmd = new NpgsqlCommand("insert into foo values (:BAR)", conn);
cmd.Parameters.Add(new NpgsqlParameter("BAR", NpgsqlDbType.Integer));
很明显这会引发错误:
cmd.Parameters[0].Value = "Hello";
cmd.ExecuteNonQuery();
出于同样的原因,这会引发错误:
insert into foo values ('Hello')
这显然有效,因为它是一个整数:
cmd.Parameters[0].Value = 5;
但您可能不知道以下内容仍然有效,因为它们是兼容的数据类型:
cmd.Parameters[0].Value = 5M;
cmd.Parameters[0].Value = 5f;
cmd.Parameters[0].Value = (short)5;
cmd.Parameters[0].Value = (long)5;
然而,即使 PostgreSQL 有足够的容忍度来接受原始 SQL:
insert into foo values ('5')
Npgsql 4 将在您尝试执行此操作时抛出您提到的错误:
cmd.Parameters[0].Value = "5";
cmd.ExecuteNonQuery();
有趣的是,我很确定它与 Npgsql 一起工作 3.x,但我认为该错误是一种改进。
因为它需要一个数字数据类型,简单的解决方案是确保你分配的任何 .Value
也是一个数字数据类型,最好是一个整数:
cmd.Parameters[0].Value = Convert.ToInt32(yourObject);
cmd.ExecuteNonQuery();
关于错误捕获的标准警告和使用 int.TryParse
。
从您上面的代码来看,您实际上可能正在将可能已经作为整数存在的内容转换为字符串。如果您取消所有这些,您可能会发现它开箱即用。在任何情况下,.Value
属性 都需要是数字。
我遇到了这个问题,我是这样解决的。在我的数据库中,我有一个类型为 Integer 的列。如果要向此列添加数据,您应该使用 NpgsqlDbType.Integer 数据类型。但是当我使用 NpgsqlDbType.String 数据类型时,我得到了那个错误。
所以你应该改变你的 NpgsqlDBtType。希望对你有帮助。
我在使用以下代码时遇到了同样的问题
var utctime = DateTimeOffset.UtcNow.ToString("yyyy-MM-dd HH:mm:ss");
writer.Write(utctime, NpgsqlDbType.TimestampTz);
所以基本上您是将 utctime 转换为字符串,但在写入数据库时使用类型作为时间戳,这不是字符串。因此它会抛出错误,因为数据与数据类型不兼容。
修复方法是不要将 utctime 转换为字符串,只需按原样使用即可。所以工作解决方案是
var utctime = DateTimeOffset.UtcNow;
writer.Write(utctime, NpgsqlDbType.TimestampTz);