首页 > 解决方案 > 使用 `NpgsqlParameter 的区别` 和 `AddWithValue` 与 `NpgsqlDbType`

问题描述

Npgsql 文档指出 using更好,NpgsqlParameter<T>因为它是强类型的,并且不会因装箱值类型导致的无用堆分配对垃圾收集器造成压力。

我有以下两个命令声明要用于特定参数的数据类型:

不使用NpgsqlParameter<T>

command.Parameters.AddWithValue("id", NpgsqlTypes.NpgsqlDbType.Integer, 123);

使用NpgsqlParameter<T>

cmd.Parameters.Add(new NpgsqlParameter<Int32>("id", NpgsqlTypes.NpgsqlDbType.Integer) { TypedValue = 123 });

我的问题是,第一个命令是否等同于第二个命令(不会将int值装箱)还是应该使用第二个命令?

我认为第一个只是告诉 Npgsql 使用什么数据类型,但仍会将int.

标签: c#postgresqlnpgsqlstrong-typing

解决方案


这并不是真正的答案,因为我相信哈维先生已经充分做到了这一点,但它比我可以发表评论的时间更长,并且没有格式......所以提前道歉。

首先,请参阅 Npgsql 的一位作者关于何时应使用通用 API 的反馈:

https://stackoverflow.com/a/51568458/1278553

另外,我没有在这篇文章中看到它,但我记得他的评论也表明新 API 的一个缺点是它不能移植到其他 ADO.net 适配器,这意味着如果您更改数据源到 Oracle,希望这不起作用。

现在谈谈我的热门运动观点……我已经看到、理解并同意不使用AddWithValue. 也就是说,我将是第一个承认我使用它的人。原因是它通常有效,而且我认为方法名称对于它正在完成的工作非常透明。

我严格避免的两种情况是:

  • 声明一次,分配多个,就像在您进行多次插入、更新(或更新插入)的事务中一样
  • 日期。由于 PostreSQL 有日期和时间戳,但 .NET 只有 System.Datetime,AddWithValue似乎假设您的意思是 System.DateTime -> 时间戳,这将导致您的程序呕吐。在这种情况下,AddWithValue 为您节省很少,因为您需要将数据类型重新声明为日期

不过,它确实适用于数组数据类型,这非常棒。

所以,你可以这样做:

cmd.Parameters.Add(new NpgsqlParameter("FOO", NpgsqlDbType.Array | NpgsqlDbType.Varchar));
cmd.Parameters[0].Value = myArray;

或者你可以这样做:

cmd.Parameters.AddWithValue("FOO", myArray);

而且效果很好……我真的很喜欢 PostgreSQL 和 NpgSql。


推荐阅读