Mono 3.12 support with SQL Server?

Does Hangfire work with SQL Server under Mono? I’m having quite a bit of trouble trying to get it going. First if I try to use the CreateSchemaIfNeeded option, Mono’s TDS handler fails and times out. After removing that part, I can’t enqueue a job, as it tries to enlist in a transaction and fails:

Hangfire.Client.CreateJobFailedException: Job creation process has bee failed. See inner exception for details ---> System.NotSupportedException: Operation is not supported.
  at System.Data.Common.DbConnection.EnlistTransaction (System.Transactions.Transaction transaction) [0x00000] in <filename unknown>:0
  at Hangfire.SqlServer.SqlServerWriteOnlyTransaction.Commit () [0x00000] in <filename unknown>:0
  at Hangfire.States.StateChangeProcess.ApplyState (Hangfire.States.ApplyStateContext context, IEnumerable`1 filters) [0x00000] in <filename unknown>:0
  at Hangfire.States.StateChangeProcess.ChangeState (Hangfire.States.StateContext context, IState toState, System.String oldStateName) [0x00000] in <filename unknown>:0
  at Hangfire.States.StateMachine.CreateInState (Hangfire.Common.Job job, IDictionary`2 parameters, IState state) [0x00000] in <filename unknown>:0
  at Hangfire.Client.CreateContext.CreateJob () [0x00000] in <filename unknown>:0
  at Hangfire.Client.JobCreationProcess+<>c__DisplayClass9.<CreateWithFilters>b__6 () [0x00000] in <filename unknown>:0
  at Hangfire.Client.JobCreationProcess.InvokeClientFilter (IClientFilter filter, Hangfire.Client.CreatingContext preContext, System.Func`1 continuation) [0x00000] in <filename unknown>:0
  --- End of inner exception stack trace ---
  at Hangfire.BackgroundJobClient.Create (Hangfire.Common.Job job, IState state) [0x00000] in <filename unknown>:0
  at Hangfire.BackgroundJobClientExtensions.Create (IBackgroundJobClient client, System.Linq.Expressions.Expression`1 methodCall, IState state) [0x00000] in <filename unknown>:0
  at Hangfire.BackgroundJobClientExtensions.Enqueue (IBackgroundJobClient client, System.Linq.Expressions.Expression`1 methodCall) [0x00000] in <filename unknown>:0
  at Hangfire.BackgroundJob.Enqueue (System.Linq.Expressions.Expression`1 methodCall) [0x00000] in <filename unknown>:0
  at hftest.Program.Main (System.String[] args) [0x00000] in <filename unknown>:0

I’m using SQL Server 2012. I’d be happy to provide a test system, or try to fix the code myself. I’d just like to know what the official line is on Mono support or any hints on what I can do to make it work.

There seems to be a Hangfire.Mono VS SLN file, but I don’t see any Mono-specific code there, just build support.

So I patched the source and it seems to work:

SqlServerWriteOnlyTransaction.cs, Commit method. Instead of using the existing connection, I create and open a connection inside the TransactionScope and pass that to the queued command functions. This avoids whatever the problem is with calling EnlistTransaction directly (maybe Mono is trying to escalate to a distributed transaction? dunno.)

With that, I’m able to queue and execute jobs on Mono, though I haven’t tested any advanced features. I tried calling GetMonitoringApi.FetchedCount(“myqueue”) but that fails[1], perhaps a problem with the ORM.

Does this seem like an acceptable hack? It looks ugly

System.NullReferenceException: Object reference not set to an instance of an object
  at System.Data.SqlClient.SqlDataReader.GetValues (System.Object[] values) [0x00000] in <filename unknown>:0
  at Dapper.SqlMapper+<>c__DisplayClass5d.<GetDapperRowDeserializer>b__5c (IDataReader r) [0x00000] in <filename unknown>:0
  at Dapper.SqlMapper+<QueryImpl>d__11`1[Dapper.SqlMapper+DapperRow].MoveNext () [0x00000] in <filename unknown>:0
  at System.Collections.Generic.List`1[Dapper.SqlMapper+DapperRow].AddEnumerable (IEnumerable`1 enumerable) [0x00000] in <filename unknown>:0
  at System.Collections.Generic.List`1[Dapper.SqlMapper+DapperRow]..ctor (IEnumerable`1 collection) [0x00000] in <filename unknown>:0
  at System.Linq.Enumerable.ToList[DapperRow] (IEnumerable`1 source) [0x00000] in <filename unknown>:0
  at Dapper.SqlMapper.Query[DapperRow] (IDbConnection cnn, System.String sql, System.Object param, IDbTransaction transaction, Boolean buffered, Nullable`1 commandTimeout, Nullable`1 commandType) [0x00000] in <filename unknown>:0
  at Dapper.SqlMapper.Query (IDbConnection cnn, System.String sql, System.Object param, IDbTransaction transaction, Boolean buffered, Nullable`1 commandTimeout, Nullable`1 commandType) [0x00000] in <filename unknown>:0
  at Hangfire.SqlServer.SqlServerJobQueueMonitoringApi.GetEnqueuedAndFetchedCount (System.String queue) [0x00000] in <filename unknown>:0
  at Hangfire.SqlServer.SqlServerMonitoringApi+<>c__DisplayClass5.<FetchedCount>b__4 (System.Data.SqlClient.SqlConnection connection) [0x00000] in <filename unknown>:0
  at Hangfire.SqlServer.SqlServerMonitoringApi.UseConnection[Int32] (System.Func`2 action) [0x00000] in <filename unknown>:0
  at Hangfire.SqlServer.SqlServerMonitoringApi.FetchedCount (System.String queue) [0x00000] in <filename unknown>:0
  at hftest.Program.Main (System.String[] args) [0x00000] in <filename unknown>:0