C#使用Npgsql时,无法使用Int32Handler处理程序写入CLR类型System.String。

5

我在尝试将整数添加到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();

听起来像是数据库问题:System.InvalidCastException:无法使用Int32Handler处理程序写入CLR类型System.String。 lambda_method(Closure,NpgsqlTypeHandler,Object,NpgsqlLengthCache&,NpgsqlParameter)中的代码出错,
在C:\ projects \ npgsql \ src \ Npgsql \ NpgsqlParameter.cs:line 553处验证并获取长度。
在C:\ projects \ npgsql \ src \ Npgsql \ NpgsqlCommand.cs:line 793处验证参数。
在C:\ projects \ npgsql \ src \ Npgsql \ NpgsqlCommand.cs:line 1141处执行DbDataReader。
在C:\ projects \ npgsql \ src \ Npgsql \ NpgsqlCommand.cs:line 1042处执行ExecuteNonQuery。
在C:\projects\npgsql\src\Npgsql\NpgsqlCommand.cs:line 1025处执行ExecuteNonQuery。
在BitcoinType.DatabaseManager.MakeInsert(Dictionary`2 requestData)中发生错误,在/Users/kamilkostrzewski/Projects/BitcoinType/BitcoinType/Program.cs:line 261行。
此处链接没有对我有帮助。
4个回答

4
我遇到了这个问题,我是这样解决的。在我的数据库中,有一个类型为Integer的列。如果你想要向这个列添加数据,你应该使用NpgsqlDbType.Integer 数据类型。但是,当我使用NpgsqlDbType.String 数据类型时,我会收到错误提示。
所以,你需要改变你的NpgsqlDBtType。希望这能帮助你。

2
假设您有以下表格:
create table foo (
  bar integer
)

如果您要准备以下方式的表插入操作:
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;

然而,即使在原始SQL中,PostgreSQL也足够宽容以接受这种情况:
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 属性需要是数字。


0

我在以下代码中遇到了相同的问题

  var utctime = DateTimeOffset.UtcNow.ToString("yyyy-MM-dd HH:mm:ss");
  writer.Write(utctime, NpgsqlDbType.TimestampTz);

基本上,您正在将utctime转换为字符串,但在使用类型为Timestamp的数据库写入时,它不是一个字符串。因此,它会抛出错误,因为数据与数据类型不兼容。

解决方法是不要将utctime强制转换为字符串,只需按原样使用即可。因此,工作解决方案如下:

  var utctime = DateTimeOffset.UtcNow;
  writer.Write(utctime, NpgsqlDbType.TimestampTz);

0

很难理解你上面的代码示例 - 你创建并填充了parameter,但是接着添加了一个完全不同的NpgsqlParameter实例到注释中。

然而,错误信息明确表示你正在尝试将字符串写入整数。这是因为你将NpgsqlParameter.Value设置为字符串值,但将其NpgsqlDbType设置为Integer。要么完全省略设置NpgsqlDbType(Npgsql通常会从值中推断出正确的类型),要么确保它们正确对齐。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接