public async Task <VoteGetModel> CastVoteAsync(VoteCreateModel voteModel) { var matchedVote = await _voteRepository .GetSingleAsync(v => v.UserId == voteModel.UserId && (v.QuestionId == null || v.QuestionId == voteModel.TargetId) && (v.AnswerId == null || v.AnswerId == voteModel.TargetId) && (v.CommentId == null || v.CommentId == voteModel.TargetId)); if (matchedVote != null) { throw new BusinessException($"User already voted on {voteModel.VoteTarget} on '{matchedVote.CreatedOn}'."); } IVoteable target = await GetVoteableFromRepositoryAsync(voteModel.VoteTarget, voteModel.TargetId); if (target == null) { throw new EntityNotFoundException(voteModel.VoteTarget.ToString(), voteModel.TargetId); } var vote = Vote.CreateVote(voteModel.UserId, target, voteModel.VoteType); target.ApplyVote(vote); await _uow.SaveAsync(); await ChangeCachedVotesSumAfterVoteCast(vote); _eventRegister.RegisterEvent <VoteCast>(new { UserId = vote.UserId, VoteType = vote.VoteType }); return(_mapper.Map <VoteGetModel>(vote)); }