.NET 数据提供者 - 我如何确定他们可以做什么?
我有可以使用不支持事务或不支持嵌套事务的提供程序执行的代码。
我将如何以编程方式确定此类支持?
例如,当使用 MySQL .NET 连接器时,下面的代码在最终提交时抛出 System.InvalidOperationException,但对于 MSSQL 工作正常。
我希望能够更改代码以适应各种提供程序,而不必根据提供程序的类型对测试进行硬编码(例如,我不想执行 if(typeof(connection) == "一些提供商名称")
)
using (IDbConnection connection = Use.Connection(ConnectionStringName))
using (IDbTransaction transaction = connection.BeginTransaction())
{
using (currentCommand = connection.CreateCommand())
{
using (IDbCommand cmd = connection.CreateCommand())
{
currentCommand = cmd;
currentCommand.Transaction = transaction;
currentCommand.ExecuteNonQuery();
}
if (PipelineExecuter.HasErrors)
{
transaction.Rollback();
}
else
{
transaction.Commit();
}
}
transaction.Commit();
}
I have code which could be executed using a Provider that doesn't support transactions, or doesn't support nested transactions.
How would I programmatically determine such support?
E.g. The code below throws a System.InvalidOperationException on the final commit when using the MySQL .NET Connector, but works fine for MSSQL.
I'd like to be able to alter the code to accommodate various providers, without having to hardcode tests based on the type of provider (E.g. I don't want to have to do if(typeof(connection) == "some provider name")
)
using (IDbConnection connection = Use.Connection(ConnectionStringName))
using (IDbTransaction transaction = connection.BeginTransaction())
{
using (currentCommand = connection.CreateCommand())
{
using (IDbCommand cmd = connection.CreateCommand())
{
currentCommand = cmd;
currentCommand.Transaction = transaction;
currentCommand.ExecuteNonQuery();
}
if (PipelineExecuter.HasErrors)
{
transaction.Rollback();
}
else
{
transaction.Commit();
}
}
transaction.Commit();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
ADO.NET 提供程序没有内置方法来提供有关其提供的功能的详细信息。 SQLite 过去也不支持嵌套事务,但 SQLite 的某些 ADO.NET 提供程序会在代码中伪造它(没有对保存点的适当支持)。在这种情况下,您永远不会遇到错误,但您可能不会获得预期的行为。
我还看到了 IDataReader 索引器的许多不同实现。过去,一些提供程序在传递不存在的字段名称时会抛出异常,并且一些提供程序会返回 null。在 ADO.NET 2.0 中,帮助文档已更新,以指示提供程序应引发异常,但如果没有检查异常,则无法确保所有提供程序均已正确更新。
因此,简而言之,System.Data.Common 命名空间和各种 ADO.NET 提供程序使使用不同的数据库变得更加容易,但您必须了解您正在使用的数据库以及它们之间的差异每个提供商(其中大多数可能是未记录的烦人的怪癖,而不是巨大的差异)。
There is no built-in way for an ADO.NET provider to give details about what capabilities they provide. SQLite used to not support nested transactions either, but some ADO.NET providers for SQLite would fake it in code (without proper support for savepoints). In that case, you'd never get errors, but you might not get the behavior you expected.
I also have seen many different implementations of the IDataReader indexer. It used to be that some providers would throw an exception when passed a field name that didn't exist, and some providers would return null. In ADO.NET 2.0 the help docs were updated to indicate that providers should throw an exception, but without checked exceptions there's no way to ensure that all providers were properly updated.
So, in short, The System.Data.Common namespace and various ADO.NET providers make it a lot easier to work with different databases, but you do have to be aware of what DB(s) you're using and the differences in each provider (most of which will probably be undocumented annoying quirks as opposed to big differences).