public void CandidateUserDictionaryTest()
        {
            //Arrange
            var candidateUser = new CandidateUserBuilder().WithStatus(10).Build();

            //Act
            var candidatePerson     = _candidateMappers.MapCandidatePerson(candidateUser, new Dictionary <Guid, CandidateSummary>(), new Dictionary <string, int>(), new Dictionary <int, int>(), new Dictionary <int, int>(), false);
            var candidate           = candidatePerson.Candidate;
            var person              = candidatePerson.Person;
            var candidateDictionary = _candidateMappers.MapCandidateDictionary(candidate);
            var personDictionary    = _candidateMappers.MapPersonDictionary(person);

            //Assert
            candidateDictionary["CandidateId"].Should().Be(candidate.CandidateId);
            candidateDictionary["PersonId"].Should().Be(candidate.PersonId);
            candidateDictionary["CandidateStatusTypeId"].Should().Be(candidate.CandidateStatusTypeId);
            candidateDictionary["DateofBirth"].Should().Be(candidate.DateofBirth);
            candidateDictionary["AddressLine1"].Should().Be(candidate.AddressLine1);
            candidateDictionary["AddressLine2"].Should().Be(candidate.AddressLine2);
            candidateDictionary["AddressLine3"].Should().Be(candidate.AddressLine3);
            candidateDictionary["AddressLine4"].Should().Be(candidate.AddressLine4);
            candidateDictionary["AddressLine5"].Should().Be(candidate.AddressLine5);
            candidateDictionary["Town"].Should().Be(candidate.Town);
            candidateDictionary["CountyId"].Should().Be(candidate.CountyId);
            candidateDictionary["Postcode"].Should().Be(candidate.Postcode);
            candidateDictionary["LocalAuthorityId"].Should().Be(candidate.LocalAuthorityId);
            candidateDictionary["Longitude"].Should().Be(candidate.Longitude);
            candidateDictionary["Latitude"].Should().Be(candidate.Latitude);
            candidateDictionary["GeocodeEasting"].Should().Be(candidate.GeocodeEasting);
            candidateDictionary["GeocodeNorthing"].Should().Be(candidate.GeocodeNorthing);
            candidateDictionary["NiReference"].Should().Be(candidate.NiReference);
            candidateDictionary["VoucherReferenceNumber"].Should().Be(candidate.VoucherReferenceNumber);
            candidateDictionary["UniqueLearnerNumber"].Should().Be(candidate.UniqueLearnerNumber);
            candidateDictionary["UlnStatusId"].Should().Be(candidate.UlnStatusId);
            candidateDictionary["Gender"].Should().Be(candidate.Gender);
            candidateDictionary["EthnicOrigin"].Should().Be(candidate.EthnicOrigin);
            candidateDictionary["EthnicOriginOther"].Should().Be(candidate.EthnicOriginOther);
            candidateDictionary["ApplicationLimitEnforced"].Should().Be(candidate.ApplicationLimitEnforced);
            candidateDictionary["LastAccessedDate"].Should().Be(candidate.LastAccessedDate);
            candidateDictionary["AdditionalEmail"].Should().Be(candidate.AdditionalEmail);
            candidateDictionary["Disability"].Should().Be(candidate.Disability);
            candidateDictionary["DisabilityOther"].Should().Be(candidate.DisabilityOther);
            candidateDictionary["HealthProblems"].Should().Be(candidate.HealthProblems);
            candidateDictionary["ReceivePushedContent"].Should().Be(candidate.ReceivePushedContent);
            candidateDictionary["ReferralAgent"].Should().Be(candidate.ReferralAgent);
            candidateDictionary["DisableAlerts"].Should().Be(candidate.DisableAlerts);
            candidateDictionary["UnconfirmedEmailAddress"].Should().Be(candidate.UnconfirmedEmailAddress);
            candidateDictionary["MobileNumberUnconfirmed"].Should().Be(candidate.MobileNumberUnconfirmed);
            candidateDictionary["DoBFailureCount"].Should().Be(candidate.DoBFailureCount);
            candidateDictionary["ForgottenUsernameRequested"].Should().Be(candidate.ForgottenUsernameRequested);
            candidateDictionary["ForgottenPasswordRequested"].Should().Be(candidate.ForgottenPasswordRequested);
            candidateDictionary["TextFailureCount"].Should().Be(candidate.TextFailureCount);
            candidateDictionary["EmailFailureCount"].Should().Be(candidate.EmailFailureCount);
            candidateDictionary["LastAccessedManageApplications"].Should().Be(candidate.LastAccessedManageApplications);
            candidateDictionary["ReferralPoints"].Should().Be(candidate.ReferralPoints);
            candidateDictionary["BeingSupportedBy"].Should().Be(candidate.BeingSupportedBy);
            candidateDictionary["LockedForSupportUntil"].Should().Be(candidate.LockedForSupportUntil);
            candidateDictionary["NewVacancyAlertEmail"].Should().Be(candidate.NewVacancyAlertEmail);
            candidateDictionary["NewVacancyAlertSMS"].Should().Be(candidate.NewVacancyAlertSMS);
            candidateDictionary["AllowMarketingMessages"].Should().Be(candidate.AllowMarketingMessages);
            candidateDictionary["ReminderMessageSent"].Should().Be(candidate.ReminderMessageSent);
            candidateDictionary["CandidateGuid"].Should().Be(candidate.CandidateGuid);

            personDictionary["PersonId"].Should().Be(person.PersonId);
            personDictionary["Title"].Should().Be(person.Title);
            personDictionary["OtherTitle"].Should().Be(person.OtherTitle);
            personDictionary["FirstName"].Should().Be(person.FirstName);
            personDictionary["MiddleNames"].Should().Be(person.MiddleNames);
            personDictionary["Surname"].Should().Be(person.Surname);
            personDictionary["LandlineNumber"].Should().Be(person.LandlineNumber);
            personDictionary["MobileNumber"].Should().Be(person.MobileNumber);
            personDictionary["Email"].Should().Be(person.Email);
            personDictionary["PersonTypeId"].Should().Be(person.PersonTypeId);
        }
        private void BulkUpsert(IList <CandidateWithHistory> candidatesWithHistory, IDictionary <Guid, CandidateSummary> candidateSummaries)
        {
            //Have to do these one at a time as need to get the id for the inserted person records
            foreach (var candidateWithHistory in candidatesWithHistory.Where(c => c.CandidatePerson.Person.PersonId == 0))
            {
                //Insert any new person records to match with candidate records
                var personId = (int)_targetDatabase.Insert(candidateWithHistory.CandidatePerson.Person);
                candidateWithHistory.CandidatePerson.Candidate.PersonId = personId;
            }

            //Update any existing person records
            _genericSyncRespository.BulkUpdate(_personTable, candidatesWithHistory.Where(c => c.CandidatePerson.Person.PersonId != 0).Select(c => _candidateMappers.MapPersonDictionary(c.CandidatePerson.Person)));

            //Bulk insert any candidates with valid ids that are not already in the database
            _genericSyncRespository.BulkInsert(_candidateTable, candidatesWithHistory.Where(c => c.CandidatePerson.Candidate.CandidateId != 0 && !candidateSummaries.ContainsKey(c.CandidatePerson.Candidate.CandidateGuid)).Select(c => _candidateMappers.MapCandidateDictionary(c.CandidatePerson.Candidate)));

            //Now insert any remaining candidates one at a time
            foreach (var candidateWithHistory in candidatesWithHistory.Where(c => c.CandidatePerson.Candidate.CandidateId == 0))
            {
                //Ensure school attended and candidate histories have the correct candidate id
                var candidateId = (int)_targetDatabase.Insert(candidateWithHistory.CandidatePerson.Candidate);
                if (candidateWithHistory.CandidatePerson.SchoolAttended != null)
                {
                    candidateWithHistory.CandidatePerson.SchoolAttended.CandidateId = candidateId;
                }
                foreach (var candidateHistory in candidateWithHistory.CandidateHistory)
                {
                    candidateHistory.CandidateId = candidateId;
                }
            }

            //Finally, update existing candidates
            _genericSyncRespository.BulkUpdate(_candidateTable, candidatesWithHistory.Where(c => c.CandidatePerson.Candidate.CandidateId != 0 && candidateSummaries.ContainsKey(c.CandidatePerson.Candidate.CandidateGuid)).Select(c => _candidateMappers.MapCandidateDictionary(c.CandidatePerson.Candidate)));

            //Insert new schools attended
            var newSchoolsAttended = candidatesWithHistory.Where(a => a.CandidatePerson.SchoolAttended != null && a.CandidatePerson.SchoolAttended.SchoolAttendedId == 0).Select(a => a.CandidatePerson.SchoolAttended);

            _genericSyncRespository.BulkInsert(_schoolsAttendedTable, newSchoolsAttended.Select(sa => sa.MapSchoolAttendedDictionary()));

            //Update existing schools attended
            var existingSchoolsAttended = candidatesWithHistory.Where(a => a.CandidatePerson.SchoolAttended != null && a.CandidatePerson.SchoolAttended.SchoolAttendedId != 0).Select(a => a.CandidatePerson.SchoolAttended);

            _genericSyncRespository.BulkUpdate(_schoolsAttendedTable, existingSchoolsAttended.Select(sa => sa.MapSchoolAttendedDictionary()));

            //Insert new candidate history records
            var newCandidateHistories = candidatesWithHistory.SelectMany(a => a.CandidateHistory).Where(a => a.CandidateHistoryId == 0);

            _genericSyncRespository.BulkInsert(_candidateHistoryTable, newCandidateHistories.Select(ah => ah.MapCandidateHistoryDictionary()));

            //Update existing candidate history records
            var existingCandidateHistories = candidatesWithHistory.SelectMany(a => a.CandidateHistory).Where(a => a.CandidateHistoryId != 0);

            _genericSyncRespository.BulkUpdate(_candidateHistoryTable, existingCandidateHistories.Select(ah => ah.MapCandidateHistoryDictionary()));
        }