.NET 数据提供者 - 我如何确定他们可以做什么?

发布于 2024-08-17 08:37:41 字数 831 浏览 10 评论 0原文

我有可以使用不支持事务或不支持嵌套事务的提供程序执行的代码。

我将如何以编程方式确定此类支持?

例如,当使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

眼眸印温柔 2024-08-24 08:37:41

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文