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的一些注意事项:
- 如果你正在写很多值类型(例如
int
,DateTime
……),这将删除所有的拳击分配。 这是否会很重要取决于您的应用 – 仔细分析。 - 在编译时已知类型时,通用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(); }