C# Npgsql 4.0参数和空值
使用Npgsql传递空值的方式如下:C# Npgsql 4.0参数和空值,c#,postgresql,npgsql,C#,Postgresql,Npgsql,使用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
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();
}
using (NpgsqlCommand cmd = new NpgsqlCommand("insert into foo values (:TEST)", conn))
{
cmd.Parameters.Add(new NpgsqlParameter<string>("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();
}
using (NpgsqlCommand cmd = new NpgsqlCommand("insert into foo values (:TEST)", conn))
{
cmd.Parameters.Add(new NpgsqlParameter<string>("TEST", NpgsqlDbType.Varchar));
cmd.Parameters[0].Value = DBNull.Value;
cmd.ExecuteNonQuery();
}
使用(npgsqlcmd=newnpgsqlcommand(“插入到foo值(:TEST)”,conn))
{
Add(新的npgsqldParameter(“TEST”,NpgsqlDbType.Varchar));
cmd.Parameters[0].Value=DBNull.Value;
cmd.ExecuteNonQuery();
}
传递DBNull.Value时,将引发常规异常:
无法将“System.DBNull”类型的对象强制转换为“System.String”类型
所有东西仍然可以使用新的无装箱参数,但新语法似乎有意义,我们希望使用它。。。但是如何解决这种数据类型断开
上面的例子是一个字符串。我想这也会影响数字和日期。我面临这个问题,现在我没有例外 下面是我如何声明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();
}
新的通用参数API确实有一个问题-它应该接受常规的.NET
null
(而不是DBNull.Value
),我打开它来跟踪它,它将在4.0.3中修复
请注意,如前所述,通用API的全部要点是避免使用Value
属性,该属性的类型为object
。如果使用泛型npgsql参数
,但分配值
,则int将被装箱,从而破坏API的用途。您应该分配给TypedValue
,它的类型为int
,并且不会装箱。这也是为什么不能分配DBNull.Value
来指示空值(它是不同的.NET类型)
关于是否应使用此新的通用API的一些注意事项:
- 如果您正在编写大量的值类型(例如,
,int
…),这将删除所有装箱分配。这是否重要取决于您的应用程序配置文件DateTime
- 当类型在编译时已知时,一般来说,泛型API应该优先于非泛型API。这允许编译器尽早检查类型正确性,并使您的代码更清晰-我们使用
而不是List
作为良好的编码,即使性能不是问题ArrayList
- 通用API的主要(唯一?)缺点是它特定于Npgsql,使您的代码无法移植到其他数据库驱动程序(尽管它是ADO.NET的一部分)
npgsqlparmeter
尝试一下,我怀疑您会得到与我相同的错误。@Hambone为什么需要使用它?啊!我明白你的意思,但在这种情况下,我认为只使用boxed参数是更少的工作和更防弹的。例如,关于日期、时间戳、数字、JSON、XML等,等等。简单地说,通用参数API确实是推荐的方式——它既不需要更多的工作,也不需要更多的防弹性——日期/时间戳或任何其他类型都不会使它们更适合传统的非通用API。但是,请注意,性能优势(保存分配)仅与值类型(例如int、DateTime)相关,而与已在堆上分配的字符串无关。使用通用参数API需要注意的唯一问题是,它特定于Npgsql-您的代码对其他数据库的可移植性较差(至少在它进入ADO.NET之前)。我完全错过了关于TypedValue
的部分。感谢您的澄清和所有附加信息。这是完美的。我希望它的另一个优点是,它会在类型不匹配时发出编译时错误/警告,所以我会找出是否是这样。至于不可移植,对我来说更好更好,所以我宁愿使用它,而不是不使用。PostgreSQL数组也可以这么说——不是很好移植,但很神奇。说到神奇,NpgSql非常棒。感谢您对一个优秀产品的所有贡献。感谢所有的积极反馈…!是的,因为TypedValue
是键入的,它将防止一些不匹配问题(严格类型总是比弱类型好…)