{"record":{"id":"5b714a1ba8421c39","repo":"tursodatabase/turso","slug":"transaction-must-be-a-tursotransaction","errorCode":null,"errorMessage":"Transaction must be a TursoTransaction.","messagePattern":"Transaction must be a TursoTransaction\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"bindings/dotnet/src/Turso.Data/TursoCommand.cs","lineNumber":96,"sourceCode":"\n    protected override DbParameterCollection DbParameterCollection => _parameterCollection;\n\n    public new virtual TursoParameterCollection Parameters => _parameterCollection;\n\n\n    protected override DbTransaction? DbTransaction\n    {\n        get => _transaction;\n        set\n        {\n            if (value is null)\n            {\n                _transaction = null;\n                return;\n            }\n\n            _transaction = value as TursoTransaction\n                           ?? throw new ArgumentException(\"Transaction must be a TursoTransaction.\", nameof(value));\n        }\n    }\n\n    protected override void Dispose(bool disposing)\n    {\n        base.Dispose(disposing);\n        _statement?.Dispose();\n    }\n\n    public override void Cancel()\n    {\n    }\n\n    public override int ExecuteNonQuery()\n    {\n        if (_connection?.IsRemote == true)\n            return ExecuteRemoteNonQueryAsync(CancellationToken.None).GetAwaiter().GetResult();\n","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/tursodatabase/turso/blob/c1e59287258d99b309e362a63f48822256e2f65f/bindings/dotnet/src/Turso.Data/TursoCommand.cs#L78-L114","documentation":"The DbTransaction setter on TursoCommand only accepts TursoTransaction (TursoCommand.cs:86-98) — the transaction object begun on the same TursoConnection. A transaction from another provider, or from a different connection, cannot be attached and throws ArgumentException; assigning null detaches cleanly.","triggerScenarios":"cmd.Transaction = sqlTransaction; where sqlTransaction came from SqlConnection.BeginTransaction(); or reassigning a command to a new connection while it still holds a transaction from the old one.","commonSituations":"Refactors that swap the connection in a helper but keep the old transaction; cross-provider code that shares System.Data.Common objects; partial migration where one branch of code still uses SqlClient transactions.","solutions":["Begin the transaction on the TursoConnection and assign that: cmd.Transaction = await tursoConn.BeginTransactionAsync(ct);","When rebinding a command to a different connection, first set cmd.Transaction = null, then assign the new TursoConnection and its transaction.","Keep connection, command, and transaction objects sourced from one provider and one connection instance."],"exampleFix":"// before\ncmd.Connection = tursoConn;\ncmd.Transaction = oldSqlTransaction; // throws ArgumentException\n\n// after\nusing var tx = tursoConn.BeginTransaction();\ncmd.Connection = tursoConn;\ncmd.Transaction = tx;","handlingStrategy":"type-guard","validationCode":"if (tx is not null && tx is not TursoTransaction)\n    throw new InvalidOperationException(\"Transaction belongs to a different provider/connection.\");","typeGuard":"static bool IsTursoTransaction(DbTransaction? t) => t is null || t is TursoTransaction;","tryCatchPattern":"try\n{\n    cmd.Transaction = tx;\n}\ncatch (ArgumentException ex) when (ex.ParamName == \"value\")\n{\n    // tx is foreign; begin a fresh transaction on the TursoConnection instead.\n}","preventionTips":["Begin transactions on the same TursoConnection whose commands will use them.","Clear cmd.Transaction before rebinding a command to a new connection.","Keep one provider per unit of work; never share DbTransaction across providers."],"tags":["dotnet","ado-net","tursodb","transaction","type-mismatch"],"backgroundTag":"ado-net-provider-type-mismatch","analyzedSha":"c1e59287258d99b309e362a63f48822256e2f65f","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}