为什么 dapper 查询会失败而 ado 调用却不会?
Why does a dapper query fail and a ado call not?
在 netcore 5 C# 中,我在应用程序启动时检查数据库是否为最新版本,如果不是,则根据特定客户安装的版本自动更新(并为每个客户执行特定操作)。
我正在重构并尝试查看是否可以用 Dapper 调用替换当前的 sql 执行调用但失败了:
一个。例如,我在一个字符串中有这样一段 sql:
SET NUMERIC_ROUNDABORT OFF
SET ANSI_PADDING, ANSI_WARNINGS, CONCAT_NULL_YIELDS_NULL, ARITHABORT, QUOTED_IDENTIFIER, ANSI_NULLS, NOCOUNT ON SET DATEFORMAT YMD SET XACT_ABORT ON
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
DECLARE @items AS CURSOR
DECLARE @item AS nvarchar(250)
SET @items = CURSOR FOR
SELECT
N'ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(t.parent_object_id)) + N'.' + QUOTENAME(OBJECT_NAME(t.parent_object_id)) + ' DROP CONSTRAINT ' + QUOTENAME(t.name) + N';'
FROM
[sys].[check_constraints] AS t
WHERE
t.is_ms_shipped = 0
OPEN @items FETCH NEXT FROM @items INTO @item WHILE @@FETCH_STATUS = 0
BEGIN
EXEC (@item)
FETCH NEXT FROM @items INTO @item
END
CLOSE @items
DEALLOCATE @items
COMMIT TRANSACTION
b。我 运行 这(在交易中)与 Dapper:
public IDbConnection DbConnection
{
get
{
return new SqlConnection(_connectionstring);
}
}
using IDbConnection db = DbConnection;
await db.ExecuteAsync(statement)
失败并显示“System.PlatformNotSupportedException:该平台不支持分布式事务。”
c。当我将 dapper 调用替换为:
string connectionString = _context.Database.GetDbConnection().ConnectionString;
SqlConnection _connection = new SqlConnection(connectionString);
await _connection.ExecuteCommandAsync(statement).ConfigureAwait(false);
它 运行 很好(以及之后的所有其他 sql 语句)
围绕它的交易是:
using (TransactionScope scope
= new TransactionScope(TransactionScopeOption.Required, System.TimeSpan.FromMinutes(10),
TransactionScopeAsyncFlowOption.Enabled))
{
// a loop with hundreds of sql files and corresponding calls
// to execute
}
(我知道 https://github.com/dotnet/runtime/issues/19318 )
应要求提供完整的堆栈跟踪
System.PlatformNotSupportedException: This platform does not support distributed transactions.
at System.Transactions.Distributed.DistributedTransactionManager.GetDistributedTransactionFromTransmitterPropagationToken(Byte[] propagationToken)
at System.Transactions.TransactionInterop.GetDistributedTransactionFromTransmitterPropagationToken(Byte[] propagationToken)
at System.Transactions.TransactionStatePSPEOperation.PSPEPromote(InternalTransaction tx)
at System.Transactions.TransactionStateDelegatedBase.EnterState(InternalTransaction tx)
at System.Transactions.EnlistableStates.Promote(InternalTransaction tx)
at System.Transactions.Transaction.Promote()
at System.Transactions.TransactionInterop.ConvertToDistributedTransaction(Transaction transaction)
at System.Transactions.TransactionInterop.GetExportCookie(Transaction transaction, Byte[] whereabouts)
at System.Data.SqlClient.SqlInternalConnection.GetTransactionCookie(Transaction transaction, Byte[] whereAbouts)
at System.Data.SqlClient.SqlInternalConnection.EnlistNonNull(Transaction tx)
at System.Data.SqlClient.SqlInternalConnection.Enlist(Transaction tx)
at System.Data.SqlClient.SqlInternalConnectionTds.Activate(Transaction transaction)
at System.Data.ProviderBase.DbConnectionInternal.ActivateConnection(Transaction transaction)
at System.Data.ProviderBase.DbConnectionPool.PrepareConnection(DbConnection owningObject, DbConnectionInternal obj, Transaction transaction)
at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionPool.WaitForPendingOpen()
--- End of stack trace from previous location ---
at Dapper.SqlMapper.ExecuteImplAsync(IDbConnection cnn, CommandDefinition command, Object param) in /_/Dapper/SqlMapper.Async.cs:line 645
根据我在评论中的想法,没有改变属性,您可以尝试添加
db.Open();
或
await db.OpenAsync().ConfigureAwait(false);
到您现有的代码中,假设差异是连接打开的次数。
猜测,但我想知道异常是否纯粹是由 属性 getter 每次返回一个新连接引起的。这意味着您可能涉及多个连接,这(当与 TransactionScope
结合使用时)可能会导致不好的事情。也许只是:
private IDbConnection _db;
public IDbConnection DbConnection
=> _db ?? CreateOpenConnection();
private IDbConnection CreateOpenConnection()
{
if (_db is null)
{
_db = new SqlConnection(_connectionstring);
_db.Open();
}
return _db;
}
在 netcore 5 C# 中,我在应用程序启动时检查数据库是否为最新版本,如果不是,则根据特定客户安装的版本自动更新(并为每个客户执行特定操作)。
我正在重构并尝试查看是否可以用 Dapper 调用替换当前的 sql 执行调用但失败了:
一个。例如,我在一个字符串中有这样一段 sql:
SET NUMERIC_ROUNDABORT OFF
SET ANSI_PADDING, ANSI_WARNINGS, CONCAT_NULL_YIELDS_NULL, ARITHABORT, QUOTED_IDENTIFIER, ANSI_NULLS, NOCOUNT ON SET DATEFORMAT YMD SET XACT_ABORT ON
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
DECLARE @items AS CURSOR
DECLARE @item AS nvarchar(250)
SET @items = CURSOR FOR
SELECT
N'ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(t.parent_object_id)) + N'.' + QUOTENAME(OBJECT_NAME(t.parent_object_id)) + ' DROP CONSTRAINT ' + QUOTENAME(t.name) + N';'
FROM
[sys].[check_constraints] AS t
WHERE
t.is_ms_shipped = 0
OPEN @items FETCH NEXT FROM @items INTO @item WHILE @@FETCH_STATUS = 0
BEGIN
EXEC (@item)
FETCH NEXT FROM @items INTO @item
END
CLOSE @items
DEALLOCATE @items
COMMIT TRANSACTION
b。我 运行 这(在交易中)与 Dapper:
public IDbConnection DbConnection
{
get
{
return new SqlConnection(_connectionstring);
}
}
using IDbConnection db = DbConnection;
await db.ExecuteAsync(statement)
失败并显示“System.PlatformNotSupportedException:该平台不支持分布式事务。”
c。当我将 dapper 调用替换为:
string connectionString = _context.Database.GetDbConnection().ConnectionString;
SqlConnection _connection = new SqlConnection(connectionString);
await _connection.ExecuteCommandAsync(statement).ConfigureAwait(false);
它 运行 很好(以及之后的所有其他 sql 语句)
围绕它的交易是:
using (TransactionScope scope
= new TransactionScope(TransactionScopeOption.Required, System.TimeSpan.FromMinutes(10),
TransactionScopeAsyncFlowOption.Enabled))
{
// a loop with hundreds of sql files and corresponding calls
// to execute
}
(我知道 https://github.com/dotnet/runtime/issues/19318 )
应要求提供完整的堆栈跟踪
System.PlatformNotSupportedException: This platform does not support distributed transactions.
at System.Transactions.Distributed.DistributedTransactionManager.GetDistributedTransactionFromTransmitterPropagationToken(Byte[] propagationToken)
at System.Transactions.TransactionInterop.GetDistributedTransactionFromTransmitterPropagationToken(Byte[] propagationToken)
at System.Transactions.TransactionStatePSPEOperation.PSPEPromote(InternalTransaction tx)
at System.Transactions.TransactionStateDelegatedBase.EnterState(InternalTransaction tx)
at System.Transactions.EnlistableStates.Promote(InternalTransaction tx)
at System.Transactions.Transaction.Promote()
at System.Transactions.TransactionInterop.ConvertToDistributedTransaction(Transaction transaction)
at System.Transactions.TransactionInterop.GetExportCookie(Transaction transaction, Byte[] whereabouts)
at System.Data.SqlClient.SqlInternalConnection.GetTransactionCookie(Transaction transaction, Byte[] whereAbouts)
at System.Data.SqlClient.SqlInternalConnection.EnlistNonNull(Transaction tx)
at System.Data.SqlClient.SqlInternalConnection.Enlist(Transaction tx)
at System.Data.SqlClient.SqlInternalConnectionTds.Activate(Transaction transaction)
at System.Data.ProviderBase.DbConnectionInternal.ActivateConnection(Transaction transaction)
at System.Data.ProviderBase.DbConnectionPool.PrepareConnection(DbConnection owningObject, DbConnectionInternal obj, Transaction transaction)
at System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionPool.WaitForPendingOpen()
--- End of stack trace from previous location ---
at Dapper.SqlMapper.ExecuteImplAsync(IDbConnection cnn, CommandDefinition command, Object param) in /_/Dapper/SqlMapper.Async.cs:line 645
根据我在评论中的想法,没有改变属性,您可以尝试添加
db.Open();
或
await db.OpenAsync().ConfigureAwait(false);
到您现有的代码中,假设差异是连接打开的次数。
猜测,但我想知道异常是否纯粹是由 属性 getter 每次返回一个新连接引起的。这意味着您可能涉及多个连接,这(当与 TransactionScope
结合使用时)可能会导致不好的事情。也许只是:
private IDbConnection _db;
public IDbConnection DbConnection
=> _db ?? CreateOpenConnection();
private IDbConnection CreateOpenConnection()
{
if (_db is null)
{
_db = new SqlConnection(_connectionstring);
_db.Open();
}
return _db;
}