public void SetJobState(string jobId, IState state)
        {
            QueueCommand(x =>
            {
                List<Task> tasks = new List<Task>();

                StateDto stateDto = new StateDto
                {
                    Id = ObjectId.GenerateNewId(),
                    JobId = int.Parse(jobId),
                    Name = state.Name,
                    Reason = state.Reason,
                    CreatedAt = _connection.GetServerTimeUtc(),
                    Data = JobHelper.ToJson(state.SerializeData())
                };
                tasks.Add(x.State.InsertOneAsync(stateDto));

                tasks.Add(x.Job.UpdateManyAsync(
                    Builders<JobDto>.Filter.Eq(_ => _.Id, int.Parse(jobId)),
                    Builders<JobDto>.Update.Set(_ => _.StateId, stateDto.Id)));

                tasks.Add(x.Job.UpdateManyAsync(Builders<JobDto>.Filter.Eq(_ => _.Id, int.Parse(jobId)),
                    Builders<JobDto>.Update.Set(_ => _.StateName, state.Name)));

                return Task.WhenAll(tasks.ToArray());
            });
        }
		public void SetJobState(string jobId, IState state)
		{
			QueueCommand(x =>
			{
				StateDto stateDto = new StateDto
				{
					Id = ObjectId.GenerateNewId(),
					JobId = int.Parse(jobId),
					Name = state.Name,
					Reason = state.Reason,
					CreatedAt = _connection.GetServerTimeUtc(),
					Data = JobHelper.ToJson(state.SerializeData())
				};
				x.State.Insert(stateDto);

				x.Job.Update(Query<JobDto>.EQ(_ => _.Id, int.Parse(jobId)),
					Update<JobDto>.Set(_ => _.StateId, stateDto.Id));

				x.Job.Update(Query<JobDto>.EQ(_ => _.Id, int.Parse(jobId)),
					Update<JobDto>.Set(_ => _.StateName, state.Name));
			});
		}
        private JobDto CreateJobInState(HangfireDbContext database, int jobId, string stateName)
        {
            var job = Job.FromExpression(() => SampleMethod("wrong"));

            var jobState = new StateDto
            {
                CreatedAt = database.GetServerTimeUtc(),
                Data = stateName == EnqueuedState.StateName
                           ? string.Format(" {{ 'EnqueuedAt': '{0}' }}", database.GetServerTimeUtc().ToString("o"))
                           : "{}",
                JobId = jobId
            };
            database.State.InsertOne(jobState);

            var jobDto = new JobDto
            {
                Id = jobId,
                InvocationData = JobHelper.ToJson(InvocationData.Serialize(job)),
                Arguments = "['Arguments']",
                StateName = stateName,
                CreatedAt = database.GetServerTimeUtc(),
                StateId = jobState.Id
            };
            database.Job.InsertOne(jobDto);

            var jobQueueDto = new JobQueueDto
            {
                FetchedAt = null,
                Id = jobId * 10,
                JobId = jobId,
                Queue = DefaultQueue
            };

            if (stateName == FetchedStateName)
            {
                jobQueueDto.FetchedAt = database.GetServerTimeUtc();
            }

            database.JobQueue.InsertOne(jobQueueDto);

            return jobDto;
        }
        private static JobQueueDto CreateJobQueueDto(HangfireDbContext connection, string queue, bool isFetched)
        {
            var state = new StateDto();
            AsyncHelper.RunSync(() => connection.State.InsertOneAsync(state));

            var job = new JobDto
            {
                CreatedAt = connection.GetServerTimeUtc(),
                StateId = state.Id
            };

            AsyncHelper.RunSync(() => connection.Job.InsertOneAsync(job));

            var jobQueue = new JobQueueDto
            {
                Queue = queue,
                JobId = job.Id
            };

            if (isFetched)
            {
                jobQueue.FetchedAt = connection.GetServerTimeUtc().AddDays(-1);
            }

            AsyncHelper.RunSync(() => connection.JobQueue.InsertOneAsync(jobQueue));

            return jobQueue;
        }
        public void GetStateData_ReturnsCorrectData()
        {
            UseConnection((database, connection) =>
            {
                var data = new Dictionary<string, string>
						{
							{ "Key", "Value" }
						};

                var jobDto = new JobDto
                {
                    Id = 1,
                    InvocationData = "",
                    Arguments = "",
                    StateName = "",
                    CreatedAt = database.GetServerTimeUtc()
                };

                AsyncHelper.RunSync(() => database.Job.InsertOneAsync(jobDto));
                var jobId = jobDto.Id;

                AsyncHelper.RunSync(() => database.State.InsertOneAsync(new StateDto
                {
                    Id = ObjectId.GenerateNewId(),
                    JobId = jobId,
                    Name = "old-state",
                    CreatedAt = database.GetServerTimeUtc()
                }));

                var stateDto = new StateDto
                {
                    Id = ObjectId.GenerateNewId(),
                    JobId = jobId,
                    Name = "Name",
                    Reason = "Reason",
                    Data = JobHelper.ToJson(data),
                    CreatedAt = database.GetServerTimeUtc()
                };
                AsyncHelper.RunSync(() => database.State.InsertOneAsync(stateDto));

                jobDto.StateId = stateDto.Id;
                AsyncHelper.RunSync(() => database.Job.ReplaceOneAsync(_ => _.Id == jobDto.Id, jobDto, new UpdateOptions()));

                var result = connection.GetStateData(jobId.ToString());
                Assert.NotNull(result);

                Assert.Equal("Name", result.Name);
                Assert.Equal("Reason", result.Reason);
                Assert.Equal("Value", result.Data["Key"]);
            });
        }