{"record":{"id":"9c8ad98b670c7a83","repo":"HangfireIO/Hangfire","slug":"sqlcommandset-for-connection-gettype-fullname","errorCode":null,"errorMessage":"SqlCommandSet for {connection.GetType().FullName} is not supported, use regular commands instead","messagePattern":"SqlCommandSet for (.+?) is not supported, use regular commands instead","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"src/Hangfire.SqlServer/SqlCommandSet.cs","lineNumber":129,"sourceCode":"                    var p = Expression.Parameter(typeof(object));\n                    var converted = Expression.Convert(p, type);\n                    return Expression.Lambda<Func<object, int>>(Expression.Call(converted, \"ExecuteNonQuery\", null), p).Compile();\n                });\n                _disposeMethod = DisposeMethod.GetOrAdd(sqlCommandSetType, static type =>\n                {\n                    var p = Expression.Parameter(typeof(object));\n                    var converted = Expression.Convert(p, type);\n                    return Expression.Lambda<Action<object>>(Expression.Call(converted, \"Dispose\", null), p).Compile();\n                });\n                _constructor = SqlCommandSetConstructor.GetOrAdd(sqlCommandSetType, static type =>\n                {\n                    var ctor = Expression.New(type);\n                    return Expression.Lambda<Func<object>>(ctor).Compile();\n                });\n            }\n            catch (Exception exception) when (exception.IsCatchableExceptionType())\n            {\n                throw new NotSupportedException($\"SqlCommandSet for {connection.GetType().FullName} is not supported, use regular commands instead\", exception);\n            }\n\n            _instance = _constructor();\n        }\n\n        public DbConnection Connection\n        {\n            set => _setConnection(_instance, value);\n        }\n\n        public DbTransaction Transaction\n        {\n            set => _setTransaction(_instance, value);\n        }\n\n        public DbCommand BatchCommand => _getBatchCommand(_instance);\n        public int CommandCount { get; private set; }\n","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/HangfireIO/Hangfire/blob/c236dd0f930f831ec151e436e138ddc429a02a72/src/Hangfire.SqlServer/SqlCommandSet.cs#L111-L147","documentation":"NotSupportedException thrown by the SqlCommandSet constructor's catch-all: any reflection/setup exception (TypeLoadException, MissingMemberException, etc.) while probing the provider's batch type is wrapped here with the connection's full type name, directing you to fall back to regular (non-batched) commands. It is the umbrella error for 'this provider can't be used for batched inserts'.","triggerScenarios":"Constructing SqlCommandSet for a DbConnection whose provider fails any of the reflection steps (type load, property binding, delegate compilation); common with an unsupported/trimmed/incompatible provider.","commonSituations":"Incompatible SqlClient version, trimmed publish, a mocked/fake DbConnection in tests, or a third-party provider that does not mirror SqlClient's internal SqlCommandSet.","solutions":["Read the InnerException to find the exact reflection failure (type missing, property missing, etc.) and address that specifically.","Switch to a supported Microsoft.Data.SqlClient / System.Data.SqlClient version and disable trimming.","If the provider is genuinely unsupported, configure Hangfire to use regular (non-batch) command execution if such an option is available, or replace the test fake with a real provider connection."],"exampleFix":"// before (fake connection in integration test)\nvar conn = new FakeDbConnection();\nusing var batch = new SqlCommandSet(conn); // -> NotSupportedException\n\n// after\nvar conn = new SqlConnection(realConnectionString);\nconn.Open();\nusing var batch = new SqlCommandSet(conn);","handlingStrategy":"try-catch","validationCode":"static bool ProviderSupportsBatch(DbConnection conn)\n{\n    try\n    {\n        var t = conn.GetType().Assembly.GetTypes().FirstOrDefault(x => x.Name == \"SqlCommandSet\");\n        if (t == null) return false;\n        foreach (var p in new[] { \"Connection\", \"Transaction\", \"BatchCommand\" })\n            if (t.GetProperty(p, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) == null)\n                return false;\n        return true;\n    }\n    catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    using var batch = new SqlCommandSet(connection);\n}\ncatch (NotSupportedException ex)\n{\n    logger.Warn(ex.InnerException, \"Falling back to regular commands for {Conn}\", connection.GetType().FullName);\n    // execute commands individually\n}","preventionTips":["Always inspect InnerException — it holds the precise reflection failure.","Don't pass mocked/fake DbConnection through the batch path.","Pin compatible provider + Hangfire.SqlServer versions and disable trimming."],"tags":["sqlserver","reflection","provider","not-supported"],"backgroundTag":null,"analyzedSha":"c236dd0f930f831ec151e436e138ddc429a02a72","analyzedAt":"2026-08-13T20:27:11.027Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}