using DocumentFormat.OpenXml.Office2010.Excel; using Exam.Application; using Exam.Infrastructure.Data.Entity; using Exam.Infrastructure.Enums; using Exam.Infrastructure.Extensions; using Exam.Share.ViewResponses.Question; using Hotline.Application.Exam.QueryExtensions.Questions; using Hotline.Exams.Sourcewares; using Hotline.Repository.SqlSugar; using Hotline.Repository.SqlSugar.DataPermissions; using Hotline.Repository.SqlSugar.Exam.Interfaces.Questions; using Hotline.Share.Dtos.Questions; using Hotline.Share.Requests.Question; using JiebaNet.Segmenter.Common; using MapsterMapper; using SqlSugar; using XF.Domain.Dependency; using XF.Domain.Entities; using Hotline.Application.Exam.Extensions; using Hotline.Application.Exam.Core.Extensions; using Hotline.Application.Exam.Constants.Messages; using Hotline.Repository.SqlSugar.Exam.Core.Constants; using NPOI.SS.Formula.Functions; using XF.Domain.Authentications; using Hotline.Tools; using Microsoft.AspNetCore.Http; using System.Dynamic; using NPOI.Util.ArrayExtensions; using System.Threading.Tasks; using Hotline.Share.Enums.Exams; using Hotline.Share.Tools; using DocumentFormat.OpenXml.Drawing; using Hotline.Application.Exam.Core.Utilities; using Hotline.Application.Exam.Interface.Questions; using Hotline.Exams.ExamManages; using Hotline.Exams.Questions; using Hotline.Repository.SqlSugar.Exam.Repositories; using Hotline.Share.Dtos.TestPapers; using Hotline.Repository.SqlSugar.Exam.Service; using Hotline.Repository.SqlSugar.Exam.Extensions; namespace Hotline.Application.Exam.Service.Questions { public class QuestionService : ApiService, IQuestionService, IScopeDependency { #region ctor private readonly IQuestionRepository _repository; private readonly IQuestionTagRepository _questionTagRepository; private readonly IQuestionOptionsRepository _questionOptionRepository; private readonly IQuestionAnswerRepository _questionAnswerRepository; private readonly IQuestionSourcewareRepository _questionSourcewareRepository; private readonly IQuestionKnowladgeRepository _questionKnowladgeRepository; private readonly IDataPermissionFilterBuilder _dataPermissionFilterBuilder; private readonly IServiceProvider _serviceProvider; private readonly IMapper _mapper; private readonly ISessionContext _sessionContext; private AddQuestionDto _addQuestionDto; public QuestionService(IQuestionRepository repository, IQuestionTagRepository questionTagRepository, IQuestionOptionsRepository questionOptionsRepository, IQuestionAnswerRepository questionAnswerRepository, IQuestionSourcewareRepository questionSourcewareRepository, IQuestionKnowladgeRepository questionKnowladgeRepository, IDataPermissionFilterBuilder dataPermissionFilterBuilder, IServiceProvider serviceProvider, IMapper mapper, ISessionContext sessionContext ) : base(repository,mapper) { _repository = repository; _questionTagRepository = questionTagRepository; _questionAnswerRepository = questionAnswerRepository; _questionOptionRepository = questionOptionsRepository; _questionSourcewareRepository = questionSourcewareRepository; _questionKnowladgeRepository = questionKnowladgeRepository; _dataPermissionFilterBuilder = dataPermissionFilterBuilder; _serviceProvider = serviceProvider; _mapper = mapper; this._sessionContext = sessionContext; } #endregion #region public method public async Task GetAsync(EntityQueryRequest entityQueryRequest) { var entity = await _repository.GetAsync(entityQueryRequest.Id); var questionDto = _mapper.Map(entity); if (questionDto != null) { questionDto.QuestionTagDtos = await GetQuestionTags(entityQueryRequest); questionDto.QuestionAnswerDto = await GetQuestionAnswer(entityQueryRequest); questionDto.QuestionKnowladgeDtos = await GetKnowladges(entityQueryRequest); questionDto.QuestionOptionsDtos = await GetQuestionOptions(entityQueryRequest); questionDto.QuestionSourcewareDtos = await GetQuestionSourcewares(entityQueryRequest); } return questionDto; } public async Task<(int, List)> GetListAsync(QuestionPagedRequest queryRequest) { var expression = queryRequest.GetExpression(); var questionTable = _repository.Queryable().Where(expression); var questionKnowladgeExpression = queryRequest.GetQuestionKnowladgeExpression(); var questionKnowladgeTable = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(questionKnowladgeExpression); var queryable = questionTable.InnerJoin(questionKnowladgeTable, (q, k) => q.Id == k.QuestionId).Select((q, k) => new QuestionViewResponse { DifficultyLevel = q.DifficultyLevel, Title = q.Title, QuestionType = q.QuestionType, Id= q.Id }); var result = await queryable.ToListAsync(); var total = await queryable.CountAsync(); return (total, result); } public async Task> GetPagedListAsync(QuestionPagedRequest queryRequest) { var expression = queryRequest.GetExpression(); var questionTable = _repository.Queryable().Where(expression); var questionTagExpression = queryRequest.GetQuestionTagExpression(); var questionTagRepository = new BaseRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var examTagRepository = new BaseRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); var questionTagTable = questionTagRepository.Queryable().Where(questionTagExpression); var allQuestionTagTable = questionTagRepository.Queryable(); var examTagExpression = queryRequest.GetExamTagExpression(); var examTagTable = examTagRepository.Queryable().Where(examTagExpression); var allExamTagTable = examTagRepository.Queryable(); var questionKnowladgeExpression = queryRequest.GetQuestionKnowladgeExpression(); var questionKnowladgeTable = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(questionKnowladgeExpression); var queryable = questionTable.InnerJoin(questionTagTable, (s, d) => s.Id == d.QuestionId).InnerJoin(examTagTable, (s,d, t) => d.TagId == t.Id) .InnerJoin(questionKnowladgeTable, (s, d, t,k) => s.Id == k.QuestionId) .Distinct() .Select((s, d, t, k) => new QuestionViewResponse { DifficultyLevel = s.DifficultyLevel, FormalEnable = s.FormalEnable, SimulateEnable = s.SimulateEnable, SortIndex = s.SortIndex, Status =s.Status, QuestionType = s.QuestionType, Title = s.Title, Id = s.Id }); var list = await queryable.ToPageListAsync(queryRequest.PageIndex, queryRequest.PageSize); var total = await queryable.CountAsync(); var questionIds = list.Select(x => x.Id); var tags = await allQuestionTagTable.Where(x => questionIds.Contains(x.QuestionId)) .InnerJoin(allExamTagTable, (q, e) => q.TagId == e.Id) .Select((q, e) => new TagQuestionDto { Id = q.QuestionId, TagId = q.TagId, Tag = e.Name }).ToListAsync(); list.ForEach(item => { item.Tag = string.Join(",", tags.Where(x => x.Id == item.Id).Select(x => x.Tag)); }); var result = new QuestionPageViewResponse { Items = list, Pagination = new Pagination(queryRequest.PageIndex, queryRequest.PageSize, total) }; return result; } public override async Task AddAsync(AddQuestionDto actionRequest, CancellationToken cancellationToken) { base.StartTran(); base.Entity= await AddQuestion(actionRequest, cancellationToken); await base.Complete(base.Entity, OperationConstant.Create); return base.Entity.Id; } public override async Task UpdateAsync(UpdateQuestionDto actionRequest, CancellationToken cancellationToken) { base.StartTran(); await base.UpdateAsync(actionRequest, cancellationToken); ResolveQuestionId(actionRequest, actionRequest.Id); _addQuestionDto = _mapper.Map(actionRequest); base.Entity.QuestionTags = await ModifyQuestionTags(actionRequest, cancellationToken); base.Entity.QuestionOptionses = await ModifyQuestionOptions(actionRequest, cancellationToken); base.Entity.QuestionAnswers = await ModifyQuestionAnswer(actionRequest, cancellationToken); base.Entity.QuestionKnowladges = await ModifyKnowladges(actionRequest, cancellationToken); base.Entity.QuestionSourcewares = await ModifySourcewares(actionRequest, cancellationToken); await base.Complete(base.Entity,OperationConstant.Update); } public override async Task DeleteAsync(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken) { await base.DeleteAsync(entityQueryRequest, cancellationToken); var tmpEntityQueryRequest = ExpressionableUtility.CreateExpression() .AndIF(entityQueryRequest.Id.IsNotNullOrEmpty(), x => x.QuestionId == entityQueryRequest.Id) .AndIF(entityQueryRequest.Ids.IsNotNullOrEmpty(), x => entityQueryRequest.Ids.Contains(x.QuestionId)) .ToEntityQueryRequest(); await DeleteQuestionTags(tmpEntityQueryRequest, cancellationToken); tmpEntityQueryRequest = ExpressionableUtility.CreateExpression() .AndIF(entityQueryRequest.Id.IsNotNullOrEmpty(), x => x.QuestionId == entityQueryRequest.Id) .AndIF(entityQueryRequest.Ids.IsNotNullOrEmpty(), x => entityQueryRequest.Ids.Contains(x.QuestionId)) .ToEntityQueryRequest(); await DeleteQuestionOptions(tmpEntityQueryRequest, cancellationToken); tmpEntityQueryRequest = ExpressionableUtility.CreateExpression() .AndIF(entityQueryRequest.Id.IsNotNullOrEmpty(), x => x.QuestionId == entityQueryRequest.Id) .AndIF(entityQueryRequest.Ids.IsNotNullOrEmpty(), x => entityQueryRequest.Ids.Contains(x.QuestionId)) .ToEntityQueryRequest(); await DeleteQuestionAnswer(tmpEntityQueryRequest, cancellationToken); tmpEntityQueryRequest = ExpressionableUtility.CreateExpression() .AndIF(entityQueryRequest.Id.IsNotNullOrEmpty(), x => x.QuestionId == entityQueryRequest.Id) .AndIF(entityQueryRequest.Ids.IsNotNullOrEmpty(), x => entityQueryRequest.Ids.Contains(x.QuestionId)) .ToEntityQueryRequest(); await DeleteKnowladges(tmpEntityQueryRequest, cancellationToken); tmpEntityQueryRequest = ExpressionableUtility.CreateExpression() .AndIF(entityQueryRequest.Id.IsNotNullOrEmpty(), x => x.QuestionId == entityQueryRequest.Id) .AndIF(entityQueryRequest.Ids.IsNotNullOrEmpty(), x => entityQueryRequest.Ids.Contains(x.QuestionId)) .ToEntityQueryRequest(); await DeleteSourcewares(tmpEntityQueryRequest, cancellationToken); } public async Task ImportExcel(IFormFile files, CancellationToken cancellationToken) { using (var stream = files.OpenReadStream()) { var contents = ExcelHelper.Read(stream, true); var questions = new List(); var examTags = await GetExamTags(contents); base.StartTran(); contents.ForEach(async item => { var questionDto = BuildQuestion(item as ExpandoObject, examTags); var question = await AddQuestion(questionDto, cancellationToken); if (question != null) questions.Add(question); }); await _repository.AddNav(questions) .Include(x => x.QuestionTags) .Include(x => x.QuestionOptionses) .Include(x => x.QuestionSourcewares) .Include(x => x.QuestionAnswers) .Include(x => x.QuestionKnowladges).ExecuteCommandAsync(); } } private async Task> GetExamTags(List contents) { var examTags = new List(); var tagNames = new List(); contents.ForEach(item => { var tagNameStr = ((ExpandoObject)item).GetValueOrDefault(ExamSystemConstants.ColumnNames[1])?.ToString(); if (tagNameStr.IsNotNullOrEmpty()) { var names = tagNameStr.Split(",").ToList(); names.ForEach(name => { if (!tagNames.Contains(name)) { tagNames.Add(name); } }); } }); var repository = new ExamRepository(_uow, _dataPermissionFilterBuilder, _serviceProvider); examTags = await repository.Queryable().Where(x => tagNames.Contains(x.Name)).ToListAsync(); return examTags; } private AddQuestionDto BuildQuestion(ExpandoObject item,List examTags) { if (item != null) { var options = new List(); ResolveOptions(options,item,6,15); var answer = item.GetValueOrDefault(ExamSystemConstants.ColumnNames[16]).ToString(); var questionDto = new AddQuestionDto { Title = item.GetValueOrDefault(ExamSystemConstants.ColumnNames[2]) != null ? item.GetValueOrDefault(ExamSystemConstants.ColumnNames[5]).ToString() : string.Empty, QuestionTagDtos = BuildQuestionTags(item.GetValueOrDefault(ExamSystemConstants.ColumnNames[1]).ToString(), examTags), DifficultyLevel = item.GetValueOrDefault(ExamSystemConstants.ColumnNames[2]).ToString().ToEnumByDesc(), QuestionType = item.GetValueOrDefault(ExamSystemConstants.ColumnNames[0]).ToString().ToEnumByDesc(), FormalEnable = item.GetValueOrDefault(ExamSystemConstants.ColumnNames[4]).ToString().ToEnumByDesc() == ECheck.Yes, SimulateEnable = item.GetValueOrDefault(ExamSystemConstants.ColumnNames[5]).ToString().ToEnumByDesc() == ECheck.Yes, }; questionDto.QuestionAnswerDto = BuildQuestionAnswer(answer, questionDto.QuestionType); questionDto.QuestionOptionsDtos = BuildQuestionOptions(options, questionDto.QuestionType, answer); return questionDto; } return null; } private List BuildQuestionOptions(List options,EQuestionType questionType,string answer) { if (questionType.CheckSelectType()) { var addQuestionOptionDtos = new List(); var index = 0; options.ForEach(item => { var addQuestionOption = new AddQuestionOptionsDto { Content = item, Label = ExamSystemConstants.Labels[index], IsAnswer = answer.Contains(ExamSystemConstants.Labels[index]) }; addQuestionOptionDtos.Add(addQuestionOption); index++; }); return addQuestionOptionDtos; } return null; } private void ResolveOptions(List options, ExpandoObject item, int start, int end) { for(int i = start; i <= end; i++) { var option = item.GetValueOrDefault(ExamSystemConstants.ColumnNames[i])?.ToString(); if (option.IsNotNullOrEmpty()) { options.Add(option.ToString()); } } } private AddQuestionAnswerDto BuildQuestionAnswer(string? content, EQuestionType questionType) { if (!questionType.CheckSelectType()) { var addQuestionAnswerDto = new AddQuestionAnswerDto { Answer = content }; return addQuestionAnswerDto; } return null; } private List BuildQuestionTags(string content,List examTags) { if (content.IsNotNullOrEmpty()) { var addQuestionTagDtos = new List(); var tagNames = content.Split(","); tagNames.ToList().ForEach(item => { var examTag = examTags.FirstOrDefault(x => x.Name == item); if (examTag != null) { addQuestionTagDtos.Add(new AddQuestionTagDto { TagId = examTag.Id }); } }); return addQuestionTagDtos; } return null; } #endregion #region private method private void ResolveQuestionId(AddQuestionDto actionRequest,string id) { actionRequest.QuestionKnowladgeDtos?.ForEach(x => x.QuestionId = id); actionRequest.QuestionOptionsDtos?.ForEach(x => x.QuestionId = id); actionRequest.QuestionSourcewareDtos?.ForEach(x => x.QuestionId = id); actionRequest.QuestionTagDtos?.ForEach(x => x.QuestionId = id); if (actionRequest.QuestionAnswerDto != null) { actionRequest.QuestionAnswerDto.QuestionId = id; } } private void ResolveQuestionId(UpdateQuestionDto actionRequest, string id) { actionRequest.QuestionKnowladgeDtos?.ForEach(x => x.QuestionId = id); actionRequest.QuestionOptionsDtos?.ForEach(x => x.QuestionId = id); actionRequest.QuestionSourcewareDtos?.ForEach(x => x.QuestionId = id); actionRequest.QuestionTagDtos?.ForEach(x => x.QuestionId = id); if (actionRequest.QuestionAnswerDto != null) { actionRequest.QuestionAnswerDto.QuestionId = id; } } private async Task> AddQuestionTags(AddQuestionDto actionRequest, CancellationToken cancellationToken) { if (actionRequest.QuestionTagDtos == null) return null; actionRequest.QuestionTagDtos.ResolveOperationStatus(); var questionTagDtos = actionRequest.QuestionTagDtos.Where(x => x.OperationStatus == EEOperationStatus.Add).ToList(); var questionTags = _mapper.Map>(questionTagDtos); questionTags.ToInsert(_sessionContext); await _questionTagRepository.ValidateAddAsync(questionTags, cancellationToken); return questionTags; } private async Task> AddQuestionOptions(AddQuestionDto actionRequest, CancellationToken cancellationToken) { if (actionRequest.QuestionOptionsDtos == null) return null; actionRequest.QuestionOptionsDtos.ResolveOperationStatus(); // 简答和填空没有选项 if (actionRequest.QuestionType == Share.Enums.Exams.EQuestionType.Essay || actionRequest.QuestionType == Share.Enums.Exams.EQuestionType.Blank) return null; var questionOptionseDtos = actionRequest.QuestionOptionsDtos.Where(x => x.OperationStatus == EEOperationStatus.Add).ToList(); var questionOptionses = _mapper.Map>(questionOptionseDtos); var sortIndex = 0; questionOptionses.ForEach(m => { m.SortIndex = sortIndex; m.Label = ExamSystemConstants.Labels[sortIndex]; sortIndex++; }); questionOptionses.ToInsert(_sessionContext); await _questionOptionRepository.ValidateAddAsync(questionOptionses, cancellationToken); return questionOptionses; } private async Task> AddQuestionAnswer(AddQuestionDto actionRequest, CancellationToken cancellationToken) { if (actionRequest.QuestionAnswerDto == null) return null; if (actionRequest.QuestionAnswerDto.Answer != null) { actionRequest.QuestionAnswerDto.OperationStatus = EEOperationStatus.Add; } // 简答和填空没有选项 if (actionRequest.QuestionType.CheckSelectType()) return null; var questionAnswer = _mapper.Map(actionRequest.QuestionAnswerDto); var questionAnswers = new List(); questionAnswer.ToInsert(_sessionContext); questionAnswers.Add(questionAnswer); await _questionAnswerRepository.ValidateAddAsync(questionAnswer, cancellationToken); return questionAnswers; } private async Task> AddSourcewares(AddQuestionDto actionRequest, CancellationToken cancellationToken) { if (actionRequest.QuestionSourcewareDtos == null) return null; actionRequest.QuestionSourcewareDtos.ResolveOperationStatus(); var questionSourcewareDtos = actionRequest.QuestionSourcewareDtos.Where(x => x.OperationStatus == EEOperationStatus.Add).ToList(); var questionSourcewares = _mapper.Map>(questionSourcewareDtos); questionSourcewares.ToInsert(_sessionContext); await _questionSourcewareRepository.ValidateAddAsync(questionSourcewares, cancellationToken); return questionSourcewares; } private async Task> AddKnowladges(AddQuestionDto actionRequest, CancellationToken cancellationToken) { if (actionRequest.QuestionKnowladgeDtos == null) return null; actionRequest.QuestionKnowladgeDtos.ResolveOperationStatus(); var questionKnoladgeDtos = actionRequest.QuestionKnowladgeDtos.Where(x => x.OperationStatus == EEOperationStatus.Add).ToList(); var questionKnowladges = _mapper.Map>(questionKnoladgeDtos); questionKnowladges.ToInsert(_sessionContext); await _questionKnowladgeRepository.ValidateAddAsync(questionKnowladges, cancellationToken); return questionKnowladges; } private async Task> UpdateSourcewares(UpdateQuestionDto actionRequest, List all, CancellationToken cancellationToken) { if (actionRequest.QuestionSourcewareDtos == null) return null; actionRequest.QuestionSourcewareDtos.ResolveOperationStatus(); var questionSourcewareDtos = actionRequest.QuestionSourcewareDtos.Where(x => x.OperationStatus == EEOperationStatus.Update).ToList(); var ids = questionSourcewareDtos.Select(x => x.Id); var questionSourcewares = all.Where(x => ids.Contains(x.Id)).ToList(); var entitys = new List(); foreach (var questionSourcewareDto in questionSourcewareDtos) { var entity = questionSourcewares.FirstOrDefault(x => x.Id == questionSourcewareDto.Id); if (entity != null) { entity.QuestionId = actionRequest.Id; entitys.Add(_mapper.Map(questionSourcewareDto, entity)); } } //questionSourcewares = _mapper.Map,List>(questionSourcewareDtos,questionSourcewares); //questionSourcewares.ForEach(x => x.QuestionId = actionRequest.Id); questionSourcewares.ToUpdate(_sessionContext); await _questionSourcewareRepository.ValidateUpdateAsync(questionSourcewares, cancellationToken); return questionSourcewares; } private async Task> UpdateKnowladges(UpdateQuestionDto actionRequest, List all, CancellationToken cancellationToken) { if (actionRequest.QuestionKnowladgeDtos == null) return null; actionRequest.QuestionKnowladgeDtos.ResolveOperationStatus(); var questionKnowladgeDtos = actionRequest.QuestionKnowladgeDtos.Where(x => x.OperationStatus == EEOperationStatus.Add).ToList(); var ids = questionKnowladgeDtos.Select(x => x.Id); var questionKnowladges = all.Where(x => ids.Contains(x.Id)).ToList(); var entitys = new List(); foreach (var questionKnowladgeDto in questionKnowladgeDtos) { var entity = questionKnowladges.FirstOrDefault(x => x.Id == questionKnowladgeDto.Id); if (entity != null) { entity.QuestionId = actionRequest.Id; entitys.Add(_mapper.Map(questionKnowladgeDto, entity)); } } //questionKnowladges = _mapper.Map, List>(questionKnowladgeDtos,questionKnowladges); //questionKnowladges.ForEach(x => x.QuestionId = actionRequest.Id); questionKnowladges.ToUpdate(_sessionContext); await _questionKnowladgeRepository.ValidateUpdateAsync(questionKnowladges, cancellationToken); return questionKnowladges; } private async Task UpdateQuestionAnswer(UpdateQuestionDto actionRequest, CancellationToken cancellationToken) { if (actionRequest.QuestionAnswerDto == null) return null; // 简单和填空没有选项 if (actionRequest.QuestionType.CheckSelectType()) return null; var questionAnswer = await _questionAnswerRepository.GetAsync(actionRequest.QuestionAnswerDto.Id); questionAnswer = _mapper.Map(actionRequest.QuestionAnswerDto, questionAnswer); questionAnswer.QuestionId = actionRequest.Id; questionAnswer.ToUpdate(_sessionContext); await _questionAnswerRepository.ValidateUpdateAsync(questionAnswer, cancellationToken); return questionAnswer; } private async Task> UpdateQuestionOptions(UpdateQuestionDto actionRequest,List all, CancellationToken cancellationToken) { if (actionRequest.QuestionOptionsDtos == null) return null; // 简单和填空没有选项 if (actionRequest.QuestionType == Share.Enums.Exams.EQuestionType.Essay || actionRequest.QuestionType == Share.Enums.Exams.EQuestionType.Blank) return null; var questionOptionsDtos = actionRequest.QuestionOptionsDtos.Where(x => x.OperationStatus == EEOperationStatus.Update).ToList(); var ids = questionOptionsDtos.Select(x => x.Id); var questionOptionses = all.Where(x => ids.Contains(x.Id)).ToList(); var entitys = new List(); foreach(var questionOptionsDto in questionOptionsDtos) { var entity = questionOptionses.FirstOrDefault(x => x.Id == questionOptionsDto.Id); if (entity != null) { entity.QuestionId = actionRequest.Id; entitys.Add(_mapper.Map(questionOptionsDto, entity)); } } //questionOptionses = _mapper.Map, List>(questionOptionsDtos,questionOptionses); //entitys.ForEach(x => x.QuestionId = actionRequest.Id); entitys.ToUpdate(_sessionContext); await _questionOptionRepository.ValidateUpdateAsync(entitys, cancellationToken); return entitys; } private async Task> UpdateQuestionTags(UpdateQuestionDto actionRequest,List all, CancellationToken cancellationToken) { if (actionRequest.QuestionTagDtos == null) return null; var questionTagDtos = actionRequest.QuestionTagDtos.Where(x => x.OperationStatus == EEOperationStatus.Update).ToList(); var ids = questionTagDtos.Select(x => x.Id); var questionTags = all.Where(x => ids.Contains(x.Id)).ToList(); var entitys = new List(); foreach (var questionOptionsDto in questionTagDtos) { var entity = questionTags.FirstOrDefault(x => x.Id == questionOptionsDto.Id); if (entity != null) { entity.QuestionId = actionRequest.Id; entitys.Add(_mapper.Map(questionOptionsDto, entity)); } } //questionTags = _mapper.Map, List>(questionTagDtos,questionTags); questionTags.ToUpdate(_sessionContext); await _questionTagRepository.ValidateUpdateAsync(questionTags, cancellationToken); return questionTags; } private async Task DeleteSourcewares(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken) { await _questionSourcewareRepository.DeleteWithValidateAsync(entityQueryRequest, cancellationToken); } private async Task DeleteKnowladges(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken) { await _questionKnowladgeRepository.DeleteWithValidateAsync(entityQueryRequest, cancellationToken); } private async Task DeleteQuestionAnswer(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken) { await _questionAnswerRepository.DeleteWithValidateAsync(entityQueryRequest, cancellationToken); } private async Task DeleteQuestionOptions(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken) { await _questionOptionRepository.DeleteWithValidateAsync(entityQueryRequest, cancellationToken); } private async Task DeleteQuestionTags(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken) { await _questionTagRepository.DeleteWithValidateAsync(entityQueryRequest, cancellationToken); } private async Task> ModifySourcewares(UpdateQuestionDto actionRequest, CancellationToken cancellationToken) { var all = await _questionSourcewareRepository.Queryable().Where(x => x.QuestionId == actionRequest.Id).ToListAsync(); if (actionRequest.QuestionSourcewareDtos == null) return null; var questionSourcewares = new List(); actionRequest.QuestionSourcewareDtos.ResolveOperationStatus(all); _addQuestionDto.QuestionSourcewareDtos = _mapper.Map, List>(actionRequest.QuestionSourcewareDtos); _addQuestionDto.QuestionSourcewareDtos.ResolveOperationStatus(); questionSourcewares.AddRangeExt(await AddSourcewares(_addQuestionDto, cancellationToken)); questionSourcewares.AddRangeExt(await UpdateSourcewares(actionRequest, all, cancellationToken)); var questionSourcewareDtos = actionRequest.QuestionSourcewareDtos.Where(x => x.OperationStatus == EEOperationStatus.Delete); var ids = questionSourcewareDtos.Select(m => m.Id); EntityQueryRequest entityQueryRequest = ResovleDelete(ids); await DeleteSourcewares(entityQueryRequest, cancellationToken); return questionSourcewares; } private async Task> ModifyKnowladges(UpdateQuestionDto actionRequest, CancellationToken cancellationToken) { var all = await _questionKnowladgeRepository.Queryable().Where(x => x.QuestionId == actionRequest.Id).ToListAsync(); if (actionRequest.QuestionKnowladgeDtos == null) return null; var questionKnowladges = new List(); actionRequest.QuestionKnowladgeDtos.ResolveOperationStatus(all); _addQuestionDto.QuestionKnowladgeDtos = _mapper.Map, List>(actionRequest.QuestionKnowladgeDtos); _addQuestionDto.QuestionKnowladgeDtos.ResolveOperationStatus(); questionKnowladges.AddRangeExt(await AddKnowladges(_addQuestionDto, cancellationToken)); questionKnowladges.AddRangeExt(await UpdateKnowladges(actionRequest, all, cancellationToken)); var questionKnowladgeDtos = actionRequest.QuestionKnowladgeDtos.Where(x => x.OperationStatus == EEOperationStatus.Delete); var ids = questionKnowladgeDtos.Select(m => m.Id); EntityQueryRequest entityQueryRequest = ResovleDelete(ids); await DeleteKnowladges(entityQueryRequest, cancellationToken); return questionKnowladges; } private async Task> ModifyQuestionAnswer(UpdateQuestionDto actionRequest, CancellationToken cancellationToken) { var all = await _questionAnswerRepository.Queryable().Where(x => x.QuestionId == actionRequest.Id).ToListAsync(); var questionAnswers = new List(); if (actionRequest.QuestionAnswerDto == null) { if (all == null) return null; else { var ids = all.Select(m => m.Id).ToList(); var entityQueryRequest = new EntityQueryRequest { Expression = ExpressionableUtility.CreateExpression() .AndIF(ids.IsNotEmpty(), x => ids.Contains(x.Id)).ToExpression() }; await DeleteQuestionAnswer(entityQueryRequest, cancellationToken); return null; } } if (actionRequest.QuestionAnswerDto.Id != null) { actionRequest.QuestionAnswerDto.OperationStatus = EEOperationStatus.Update; var update = await UpdateQuestionAnswer(actionRequest, cancellationToken); if (update != null) { questionAnswers.Add(update); } } else { var add = await AddQuestionAnswer(_addQuestionDto, cancellationToken); if (add != null) { questionAnswers.AddRange(add); } } if (actionRequest.QuestionAnswerDto != null && actionRequest.QuestionAnswerDto.OperationStatus == EEOperationStatus.Delete) { var entityQueryRequest = new EntityQueryRequest { Id = actionRequest.QuestionAnswerDto?.Id }; await DeleteQuestionAnswer(entityQueryRequest, cancellationToken); } return questionAnswers; } private async Task> ModifyQuestionOptions(UpdateQuestionDto actionRequest, CancellationToken cancellationToken) { if (actionRequest.QuestionOptionsDtos == null) return null; var questionOptions = new List(); var all = await _questionOptionRepository.Queryable().Where(x=>x.QuestionId == actionRequest.Id).ToListAsync(); actionRequest.QuestionOptionsDtos.ResolveOperationStatus(all); _addQuestionDto.QuestionOptionsDtos = _mapper.Map, List>(actionRequest.QuestionOptionsDtos); _addQuestionDto.QuestionOptionsDtos.ResolveOperationStatus(); questionOptions.AddRangeExt(await AddQuestionOptions(_addQuestionDto, cancellationToken)); questionOptions.AddRangeExt(await UpdateQuestionOptions(actionRequest, all, cancellationToken)); var questionOptionsDtos = actionRequest.QuestionOptionsDtos.Where(x => x.OperationStatus == EEOperationStatus.Delete); var ids = questionOptionsDtos.Select(m => m.Id); EntityQueryRequest entityQueryRequest = ResovleDelete(ids); await DeleteQuestionOptions(entityQueryRequest, cancellationToken); return questionOptions; } private async Task> ModifyQuestionTags(UpdateQuestionDto actionRequest, CancellationToken cancellationToken) { if (actionRequest.QuestionTagDtos == null) return null; var questionTags = new List(); var all = await _questionTagRepository.Queryable().Where(x => x.QuestionId == actionRequest.Id).ToListAsync(); actionRequest.QuestionTagDtos.ResolveOperationStatus(all); _addQuestionDto.QuestionTagDtos = _mapper.Map, List>(actionRequest.QuestionTagDtos); questionTags.AddRangeExt(await AddQuestionTags(_addQuestionDto, cancellationToken)); questionTags.AddRangeExt(await UpdateQuestionTags(actionRequest, all, cancellationToken)); var questionTagDtos = actionRequest.QuestionTagDtos.Where(x => x.OperationStatus == EEOperationStatus.Delete); var ids = questionTagDtos.Select(m => m.Id); EntityQueryRequest entityQueryRequest = ResovleDelete(ids); await DeleteQuestionTags(entityQueryRequest, cancellationToken); return questionTags; } private EntityQueryRequest ResovleDelete(IEnumerable ids) where T:class,IEntity,new() { Expressionable expressionable = ExpressionableUtility.CreateExpression(); expressionable.AndIF(ids.Any(), x => ids.Contains(x.Id)); var entityQueryRequest = new EntityQueryRequest { Expression = ids.Any() ? expressionable.ToExpression() : null }; return entityQueryRequest; } private async Task> GetQuestionSourcewares(EntityQueryRequest entityQueryRequest) { var questionSourcewareTable = _questionSourcewareRepository.Queryable().Where(x => x.QuestionId == entityQueryRequest.Id); var sourcewareTable = new ExamRepository(_questionSourcewareRepository.UOW, _dataPermissionFilterBuilder, _serviceProvider).Queryable(); var questionSourcewares = questionSourcewareTable.InnerJoin(sourcewareTable, (q, s) => q.SourcewareId == s.Id).Select((q, s) => new QuestionSourcewareDto { Id = q.Id, SourcewareId = q.SourcewareId, Name = s.Name }); return await questionSourcewares.ToListAsync(); } private async Task> GetQuestionOptions(EntityQueryRequest entityQueryRequest) { var questionOptionTable = await _questionOptionRepository.Queryable().Where(x => x.QuestionId == entityQueryRequest.Id).ToListAsync(); var questionOptions = _mapper.Map>(questionOptionTable); return questionOptions; } private async Task> GetKnowladges(EntityQueryRequest entityQueryRequest) { var questionKnowladgeTable = await _questionKnowladgeRepository.Queryable().Where(x => x.QuestionId == entityQueryRequest.Id).ToListAsync(); var questionKnowladges = _mapper.Map>(questionKnowladgeTable); return questionKnowladges; } private async Task GetQuestionAnswer(EntityQueryRequest entityQueryRequest) { var questionAnswer = await _questionAnswerRepository.GetAsync(x=>x.QuestionId == entityQueryRequest.Id); var questionAnswerDto = _mapper.Map(questionAnswer); return questionAnswerDto; } private async Task> GetQuestionTags(EntityQueryRequest entityQueryRequest) { var questionTags = _questionTagRepository.Queryable().Where(x => x.QuestionId == entityQueryRequest.Id); var examTags = new ExamRepository(_questionTagRepository.UOW, _dataPermissionFilterBuilder, _serviceProvider).Queryable(); var questionTagDtos = questionTags.InnerJoin(examTags, (q, t) => q.TagId == t.Id).Select((q, t) => new QuestionTagDto { Id = q.Id, TagId = q.TagId, Tag = t.Name, QuestionId = q.QuestionId }); return await questionTagDtos.ToListAsync(); } private async Task AddQuestion(AddQuestionDto actionRequest, CancellationToken cancellationToken) { var id = await base.AddAsync(actionRequest, cancellationToken); ResolveQuestionId(actionRequest, id); base.Entity.QuestionTags = await AddQuestionTags(actionRequest, cancellationToken); base.Entity.QuestionOptionses = await AddQuestionOptions(actionRequest, cancellationToken); base.Entity.QuestionAnswers = await AddQuestionAnswer(actionRequest, cancellationToken); base.Entity.QuestionKnowladges = await AddKnowladges(actionRequest, cancellationToken); base.Entity.QuestionSourcewares = await AddSourcewares(actionRequest, cancellationToken); return base.Entity; } #endregion #region protected method //protected override async Task CompleteAdd(Question entity) //{ // if (entity.QuestionType.CheckSelectType()) // { // await base.AddNav(entity) // .Include(x => x.QuestionTags) // .Include(x => x.QuestionOptionses) // .Include(x => x.QuestionSourcewares) // .Include(x => x.QuestionKnowladges).ExecuteCommandAsync(); // } // else // { // await base.AddNav(entity) // .Include(x => x.QuestionTags) // .Include(x => x.QuestionAnswerE) // .Include(x => x.QuestionSourcewares) // .Include(x => x.QuestionKnowladges).ExecuteCommandAsync(); // } //} //protected override async Task CompleteUpdate(Question entity) //{ // if (entity.QuestionType.CheckSelectType()) // { // await base.UpdateNav(entity) // .Include(x => x.QuestionTags,new UpdateNavOptions // { // OneToManyInsertOrUpdate = true // }) // .Include(x => x.QuestionOptionses, new UpdateNavOptions // { // OneToManyInsertOrUpdate = true // }) // .Include(x => x.QuestionSourcewares, new UpdateNavOptions // { // OneToManyInsertOrUpdate = true // }) // .Include(x => x.QuestionKnowladges, new UpdateNavOptions // { // OneToManyInsertOrUpdate = true // }).ExecuteCommandAsync(); // } // else // { // await base.UpdateNav(entity) // .Include(x => x.QuestionTags, new UpdateNavOptions // { // OneToManyInsertOrUpdate = true // }) // .Include(x => x.QuestionAnswerE) // .Include(x => x.QuestionSourcewares, new UpdateNavOptions // { // OneToManyInsertOrUpdate = true // }) // .Include(x => x.QuestionKnowladges, new UpdateNavOptions // { // OneToManyInsertOrUpdate = true // }).ExecuteCommandAsync(); // } //} #endregion } }