DataReader (DbCommand) 如何处理数据库通信?
How does DataReader (DbCommand) handle DB communication?
在我试图理解的软件中,DataReader class 是通过 ExecuteReader() 从 IDbCommand 类型(继承的)接收的。
我对 C# 和数据库通信还很陌生,所以:DataReader 如何处理与数据库的通信?
- 执行时是否收到查询的完整响应
ExecuteReader(),然后使用 reader.Read() 在本地单步执行响应?
- 或者每个 reader.Read() 调用是否通过网络从数据库中获取下一项?
- 或者,还有其他我没有想到的?
从技术上讲,"it depends",因为 DbDataReader
是一个抽象 class,可以以您认为合适的任何方式实现——包括缓冲整个结果。
但实际上,界面适合零碎阅读,实现也是如此。如果我们以 SqlDataReader
为例,初始调用 .ExecuteReader()
将开始处理命令并使服务器提供结果,然后每次调用 .Read()
将获取一行网络。但是,并非每次调用 .Read()
都必然涉及网络流量,因为多个行可能捆绑在一个数据包中,因此可以从缓冲区中满足读取。
这同样适用于列,甚至 - 它们可能跨越网络数据包甚至包含流,因此所有 .GetX()
方法都可能涉及额外的网络往返(这就是为什么它们都具有 Async
.NET 4.5 及更高版本)。
在我试图理解的软件中,DataReader class 是通过 ExecuteReader() 从 IDbCommand 类型(继承的)接收的。
我对 C# 和数据库通信还很陌生,所以:DataReader 如何处理与数据库的通信?
- 执行时是否收到查询的完整响应 ExecuteReader(),然后使用 reader.Read() 在本地单步执行响应?
- 或者每个 reader.Read() 调用是否通过网络从数据库中获取下一项?
- 或者,还有其他我没有想到的?
从技术上讲,"it depends",因为 DbDataReader
是一个抽象 class,可以以您认为合适的任何方式实现——包括缓冲整个结果。
但实际上,界面适合零碎阅读,实现也是如此。如果我们以 SqlDataReader
为例,初始调用 .ExecuteReader()
将开始处理命令并使服务器提供结果,然后每次调用 .Read()
将获取一行网络。但是,并非每次调用 .Read()
都必然涉及网络流量,因为多个行可能捆绑在一个数据包中,因此可以从缓冲区中满足读取。
这同样适用于列,甚至 - 它们可能跨越网络数据包甚至包含流,因此所有 .GetX()
方法都可能涉及额外的网络往返(这就是为什么它们都具有 Async
.NET 4.5 及更高版本)。