Npgsql 4.0参数和空值

使用Npgsql传递空值看起来像这样:

using (NpgsqlCommand cmd = new NpgsqlCommand("insert into foo values (:TEST)", conn)) { cmd.Parameters.Add(new NpgsqlParameter("TEST", NpgsqlDbType.Varchar)); cmd.Parameters[0].Value = DBNull.Value; cmd.ExecuteNonQuery(); } 

哪个工作正常。

新的Npgsql 4.0文档建议使用强数据类型声明参数,如下所示:

 using (NpgsqlCommand cmd = new NpgsqlCommand("insert into foo values (:TEST)", conn)) { cmd.Parameters.Add(new NpgsqlParameter("TEST", NpgsqlDbType.Varchar)); cmd.Parameters[0].Value = DBNull.Value; cmd.ExecuteNonQuery(); } 

传递DBNull.Value时,抛出一般exception:

无法将类型为“System.DBNull”的对象强制转换为“System.String”。

一切仍然适用于新的无拳击参数,但新语法似乎有意义,我们想要使用它…但如何解决此数据类型断开连接?

上面的例子是一个字符串。 我认为这也会影响数字和日期。

新的通用参数API确实有一个问题 – 它应该接受常规.NET null (而不是DBNull.Value ),我已经打开这个问题来跟踪它,它将在4.0.3中修复。

请注意,正如文档说明所述,通用API的重点是避免使用Value属性,它是object类型。 如果您使用通用的NpgsqlParameter但是赋值,那么您的int将被装箱, NpgsqlParameter了API的用途。 您应该分配给TypedValue ,它是int类型而不是box。 这也是为什么你不能指定DBNull.Value来指示一个空值(它是一个不同的.NET类型)的原因。

关于是否应该使用这个新通用API的一些注意事项:

  • 如果你正在写很多值类型(例如intDateTime ……),这将删除所有的拳击分配。 这是否会很重要取决于您的应用 – 仔细分析。
  • 在编译时已知类型时,通用API通常应始终优先于非genericsAPI。 这允许编译器尽早检查类型的正确性并使代码更清晰 – 我们使用List而不是ArrayList作为良好编码的问题,即使性能不是问题
  • 通用API的主要(唯一?)缺点是它是特定于Npgsql的,使得您的代码不可移植到其他数据库驱动程序(尽管存在使这个(或类似的)成为ADO.NET的一部分的问题)。

我遇到了这个问题,现在我没有得到它的例外

我在这里如何声明Postgres函数的参数:

 string test; using (NpgsqlCommand cmd = new NpgsqlCommand("insert into foo values (:TEST)", conn)) { cmd.Parameters.AddWithValue("TEST", NpgsqlTypes.NpgsqlDbType.Varchar, (object)test?? DBNull.Value); cmd.ExecuteNonQuery(); }