ExtractRuleService.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. using DocumentFormat.OpenXml.Office2010.Excel;
  2. using Exam.Application.Interface.Exam;
  3. using Exam.Infrastructure.Data.Entity;
  4. using Exam.Infrastructure.Enums;
  5. using Exam.Infrastructure.Extensions;
  6. using Exam.Share.ViewResponses.Exam;
  7. using Hotline.Application.Exam.Core.Extensions;
  8. using Hotline.Application.Exam.Core.Utilities;
  9. using Hotline.Application.Exam.Extensions;
  10. using Hotline.Application.Exam.Interface.ExamManages;
  11. using Hotline.Application.Exam.QueryExtensions.ExamManages;
  12. using Hotline.Exams.ExamManages;
  13. using Hotline.Exams.Questions;
  14. using Hotline.Repository.SqlSugar;
  15. using Hotline.Repository.SqlSugar.DataPermissions;
  16. using Hotline.Repository.SqlSugar.Exam.Core.Constants;
  17. using Hotline.Repository.SqlSugar.Exam.Extensions;
  18. using Hotline.Repository.SqlSugar.Exam.Interfaces.ExamManages;
  19. using Hotline.Repository.SqlSugar.Exam.Interfaces.Questions;
  20. using Hotline.Repository.SqlSugar.Exam.Repositories;
  21. using Hotline.Repository.SqlSugar.Exam.Service;
  22. using Hotline.Share.Dtos.TestPapers;
  23. using Hotline.Share.Requests.Exam;
  24. using Hotline.Share.Tools;
  25. using Hotline.Share.ViewResponses.Exam;
  26. using JiebaNet.Segmenter.Common;
  27. using MapsterMapper;
  28. using SqlSugar;
  29. using XF.Domain.Authentications;
  30. using XF.Domain.Dependency;
  31. using ExamQuestion = Hotline.Exams.Questions.ExamQuestion;
  32. namespace Hotline.Application.Exam.Service.ExamManages
  33. {
  34. public class ExtractRuleService : ApiService<ExamExtractRule, AddExtractRuleDto, UpdateExtractRuleDto, HotlineDbContext>, IExtractRuleService, IScopeDependency
  35. {
  36. private readonly IExtractRuleRepository _repository;
  37. private readonly ITagQuestionRepository _tagQuestionRepository;
  38. private readonly IRuleTagRepository _ruleTagRepository;
  39. private readonly ISessionContext _sessionContext;
  40. private readonly IDataPermissionFilterBuilder _dataPermissionFilterBuilder;
  41. private readonly IServiceProvider _serviceProvider;
  42. private readonly IMapper _mapper;
  43. private AddExtractRuleDto _addExtractRuleDto;
  44. public ExtractRuleService(IExtractRuleRepository repository,
  45. ITagQuestionRepository tagQuestionRepository,
  46. IRuleTagRepository ruleTagRepository,
  47. ISessionContext sessionContext,
  48. IDataPermissionFilterBuilder dataPermissionFilterBuilder, IServiceProvider serviceProvider,
  49. IMapper mapper) : base(repository, mapper, sessionContext)
  50. {
  51. _repository = repository;
  52. _tagQuestionRepository = tagQuestionRepository;
  53. _ruleTagRepository = ruleTagRepository;
  54. this._sessionContext = sessionContext;
  55. _dataPermissionFilterBuilder = dataPermissionFilterBuilder;
  56. _serviceProvider = serviceProvider;
  57. _mapper = mapper;
  58. }
  59. #region public method
  60. /// <summary>
  61. ///
  62. /// </summary>
  63. /// <param name="entityQueryRequest"></param>
  64. /// <returns></returns>
  65. public async Task<ExtractRuleDto> GetAsync(EntityQueryRequest entityQueryRequest)
  66. {
  67. var entity = await _repository.GetAsync(entityQueryRequest.Id);
  68. var extractRuleDto = _mapper.Map<ExtractRuleDto>(entity);
  69. if (extractRuleDto != null)
  70. {
  71. extractRuleDto.RuleTagDtos = await GetRuleTagDtos(entityQueryRequest);
  72. extractRuleDto.TagQuestionDtos = await GetTagQuestions(entityQueryRequest);
  73. var tagQuestionCounts = await GetTagQuestionCountAsync(new TagQuestionRequest
  74. {
  75. TagIds = extractRuleDto.RuleTagDtos.Select(x=>x.TagId).ToList()
  76. });
  77. extractRuleDto.TagQuestionDtos.ForEach(item =>
  78. {
  79. var tagQuestionCount = tagQuestionCounts.FirstOrDefault(m => m.TagId == item.TagId && m.QuestionType == item.QuestionType);
  80. item.TotalCount = tagQuestionCount?.TotalCount ?? 0;
  81. });
  82. }
  83. return extractRuleDto;
  84. }
  85. public async Task<(int, List<ExtractRuleViewResponse>)> GetListAsync(ExtractRulePagedRequest queryRequest)
  86. {
  87. queryRequest.Status = queryRequest.Status ?? Share.Enums.Exams.EPublicStatus.Valid;
  88. ISugarQueryable<ExtractRuleViewResponse> queryable = QueryResult(queryRequest);
  89. var result = await queryable.ToListAsync();
  90. var total = await queryable.CountAsync();
  91. return (total, result);
  92. }
  93. public async Task<PageViewResponse<ExtractRuleViewResponse>> GetPagedListAsync(ExtractRulePagedRequest queryRequest)
  94. {
  95. ISugarQueryable<ExtractRuleViewResponse> queryable = QueryResult(queryRequest);
  96. var list = await queryable.ToPageListAsync(queryRequest.PageIndex, queryRequest.PageSize);
  97. var total = await queryable.CountAsync();
  98. var result = new ExtractRulePageViewResponse
  99. {
  100. Items = list,
  101. Pagination = new Pagination(queryRequest.PageIndex, queryRequest.PageSize, total)
  102. };
  103. return result;
  104. }
  105. /// <summary>
  106. /// 新增抽题规则
  107. /// </summary>
  108. /// <param name="actionRequest"></param>
  109. /// <param name="cancellationToken"></param>
  110. /// <returns></returns>
  111. public override async Task<string> AddAsync(AddExtractRuleDto actionRequest, CancellationToken cancellationToken)
  112. {
  113. base.StartTran();
  114. var id = await base.AddAsync(actionRequest, cancellationToken);
  115. ResolveExtractRuleId(actionRequest, id);
  116. base.Entity.RuleTags = await AddRuleTags(actionRequest, cancellationToken);
  117. base.Entity.TagQuestions = await AddTagQuestions(actionRequest, cancellationToken);
  118. await base.Complete(base.Entity, OperationConstant.Create);
  119. return id;
  120. }
  121. /// <summary>
  122. /// 修改抽题规则
  123. /// </summary>
  124. /// <param name="actionRequest"></param>
  125. /// <param name="cancellationToken"></param>
  126. /// <returns></returns>
  127. public override async Task UpdateAsync(UpdateExtractRuleDto actionRequest, CancellationToken cancellationToken)
  128. {
  129. base.StartTran();
  130. await base.UpdateAsync(actionRequest, cancellationToken);
  131. ResolveExtractRuleId(actionRequest, actionRequest.Id);
  132. ResolveAddExtractRuleDto(actionRequest);
  133. base.Entity.RuleTags = await ModifyRuleTags(actionRequest, cancellationToken);
  134. base.Entity.TagQuestions = await ModifyTagQuestions(actionRequest, cancellationToken);
  135. await base.Complete(base.Entity, OperationConstant.Update);
  136. }
  137. private void ResolveAddExtractRuleDto(UpdateExtractRuleDto actionRequest)
  138. {
  139. _addExtractRuleDto = _mapper.Map<AddExtractRuleDto>(actionRequest);
  140. //_addExtractRuleDto.RuleTagDtos = new List<AddRuleTagDto>();
  141. //actionRequest.RuleTagDtos.ToList().ForEach(item =>
  142. //{
  143. // _addExtractRuleDto.RuleTagDtos.Add(_mapper.Map<AddRuleTagDto>(item));
  144. //});
  145. //_addExtractRuleDto.TagQuestionDtos = new List<AddTagQuestionDto>();
  146. //actionRequest.TagQuestionDtos.ToList().ForEach(item =>
  147. //{
  148. // _addExtractRuleDto.TagQuestionDtos.Add(_mapper.Map<AddTagQuestionDto>(item));
  149. //});
  150. }
  151. /// <summary>
  152. /// 删除抽题规则
  153. /// </summary>
  154. /// <param name="entityQueryRequest"></param>
  155. /// <param name="cancellationToken"></param>
  156. /// <returns></returns>
  157. public override async Task DeleteAsync(EntityQueryRequest entityQueryRequest, CancellationToken cancellationToken)
  158. {
  159. await base.DeleteAsync(entityQueryRequest, cancellationToken);
  160. var tempEntityQueryRequest = ExpressionableUtility.CreateExpression<ExamTagQuestion>()
  161. .AndIF(entityQueryRequest.Id.IsNotNullOrEmpty(), x => x.RuleId == entityQueryRequest.Id)
  162. .AndIF(entityQueryRequest.Ids.IsNotNullOrEmpty(), x => entityQueryRequest.Ids.Contains(x.RuleId)).ToEntityQueryRequest<ExamTagQuestion>();
  163. await DeleteTagQuestions(tempEntityQueryRequest, cancellationToken);
  164. tempEntityQueryRequest = ExpressionableUtility.CreateExpression<ExamRuleTag>()
  165. .AndIF(entityQueryRequest.Id.IsNotNullOrEmpty(), x => x.RuleId == entityQueryRequest.Id)
  166. .AndIF(entityQueryRequest.Ids.IsNotNullOrEmpty(), x => entityQueryRequest.Ids.Contains(x.RuleId)).ToEntityQueryRequest<ExamRuleTag>();
  167. await DeleteRuleTags(tempEntityQueryRequest, cancellationToken);
  168. }
  169. /// <summary>
  170. /// 获取标题试题数
  171. /// </summary>
  172. /// <param name="tagQuestionRequest"></param>
  173. /// <returns></returns>
  174. public async Task<List<TagQuestionViewResponse>> GetTagQuestionCount(TagQuestionRequest tagQuestionRequest)
  175. {
  176. if (tagQuestionRequest.TagIds.IsNullOrEmpty()) return new List<TagQuestionViewResponse>();
  177. return await GetTagQuestionCountAsync(tagQuestionRequest);
  178. }
  179. #endregion
  180. #region private method
  181. /// <summary>
  182. /// 获取查询结果
  183. /// </summary>
  184. /// <param name="queryRequest"></param>
  185. /// <returns></returns>
  186. private ISugarQueryable<ExtractRuleViewResponse> QueryResult(ExtractRulePagedRequest queryRequest)
  187. {
  188. var expression = queryRequest.GetExpression();
  189. var query = _repository.Queryable().Where(expression);
  190. var querable = query.OrderBy(o => o.SortIndex).Select(m => new ExtractRuleViewResponse
  191. {
  192. Name = m.Name,
  193. Id = m.Id,
  194. Status = m.Status,
  195. Code = m.Code,
  196. SortIndex = m.SortIndex,
  197. Remark = m.Remark,
  198. ExamType = m.RuleType
  199. });
  200. return querable;
  201. }
  202. /// <summary>
  203. /// 新增标签试题
  204. /// </summary>
  205. /// <param name="actionRequest"></param>
  206. /// <param name="cancellationToken"></param>
  207. /// <returns></returns>
  208. private async Task<List<ExamTagQuestion>> AddTagQuestions(AddExtractRuleDto actionRequest, CancellationToken cancellationToken)
  209. {
  210. if (actionRequest.TagQuestionDtos == null) return null;
  211. actionRequest.TagQuestionDtos.ResolveOperationStatus();
  212. var tagQuestionDtos = actionRequest.TagQuestionDtos.Where(x => x.OperationStatus == EEOperationStatus.Add && x.Count!=null).ToList();
  213. var tagQuestions = _mapper.Map<List<ExamTagQuestion>>(tagQuestionDtos);
  214. tagQuestions.ToInsert(_sessionContext);
  215. await _tagQuestionRepository.ValidateAddAsync(tagQuestions, cancellationToken);
  216. return tagQuestions;
  217. }
  218. /// <summary>
  219. /// 新增规则标签
  220. /// </summary>
  221. /// <param name="actionRequest"></param>
  222. /// <param name="cancellationToken"></param>
  223. /// <returns></returns>
  224. private async Task<List<ExamRuleTag>> AddRuleTags(AddExtractRuleDto actionRequest, CancellationToken cancellationToken)
  225. {
  226. if (actionRequest.RuleTagDtos == null) return null;
  227. actionRequest.RuleTagDtos.ResolveOperationStatus();
  228. var ruleTagDtos = actionRequest.RuleTagDtos.Where(x => x.OperationStatus == EEOperationStatus.Add).ToList();
  229. var ruleTags = _mapper.Map<List<ExamRuleTag>>(ruleTagDtos);
  230. ruleTags.ToInsert(_sessionContext);
  231. await _ruleTagRepository.ValidateAddAsync(ruleTags, cancellationToken);
  232. return ruleTags;
  233. }
  234. /// <summary>
  235. /// 修改标签试题数
  236. /// </summary>
  237. /// <param name="actionRequest"></param>
  238. /// <param name="cancellationToken"></param>
  239. /// <returns></returns>
  240. /// <exception cref="NotImplementedException"></exception>
  241. private async Task<List<ExamTagQuestion>> ModifyTagQuestions(UpdateExtractRuleDto actionRequest, CancellationToken cancellationToken)
  242. {
  243. if (actionRequest.TagQuestionDtos == null) return null;
  244. //var all = await _tagQuestionRepository.Queryable().Where(m => m.RuleId == actionRequest.Id).ToListAsync();
  245. //actionRequest.TagQuestionDtos.ResolveOperationStatus(all);
  246. var entityQueyRequest = ExpressionableUtility.CreateExpression<ExamTagQuestion>()
  247. .AndIF(actionRequest.Id.IsNotNullOrEmpty(), x => x.RuleId == actionRequest.Id).ToEntityQueryRequest<ExamTagQuestion>();
  248. await DeleteTagQuestions(entityQueyRequest, cancellationToken);
  249. var tagQuestions = new List<ExamTagQuestion>();
  250. tagQuestions.AddRangeExt(await AddTagQuestions(_addExtractRuleDto, cancellationToken));
  251. //tagQuestions.AddRangeExt(await UpdateTagQuestions(actionRequest, all, cancellationToken));
  252. //var ruleTagDtos = actionRequest.TagQuestionDtos.Where(x => x.OperationStatus == EEOperationStatus.Delete).ToList();
  253. //var ids = ruleTagDtos.Select(x => x.Id).ToList();
  254. //var entityQueyRequest = ExpressionableUtility.CreateExpression<TagQuestion>()
  255. // .AndIF(ids.IsNotNull(), x => ids.Contains(x.Id)).ToEntityQueryRequest<TagQuestion>();
  256. await DeleteTagQuestions(entityQueyRequest, cancellationToken);
  257. return tagQuestions;
  258. }
  259. /// <summary>
  260. /// 修改标签试题数
  261. /// </summary>
  262. /// <param name="actionRequest"></param>
  263. /// <param name="cancellationToken"></param>
  264. /// <returns></returns>
  265. /// <exception cref="NotImplementedException"></exception>
  266. private async Task<List<ExamTagQuestion>> UpdateTagQuestions(UpdateExtractRuleDto actionRequest, List<ExamTagQuestion> all, CancellationToken cancellationToken)
  267. {
  268. if (actionRequest.TagQuestionDtos == null) return null;
  269. var tagQuestionDtos = actionRequest.TagQuestionDtos.Where(x => x.OperationStatus == EEOperationStatus.Update).ToList();
  270. var ids = tagQuestionDtos.Select(x => x.Id).ToList();
  271. var tagQuestions = all.Where(x => ids.Contains(x.Id)).ToList();
  272. var entitys = new List<ExamTagQuestion>();
  273. tagQuestionDtos.ForEach(x =>
  274. {
  275. var entity = tagQuestions.FirstOrDefault(x => x.Id == x.Id);
  276. entity = _mapper.Map(x, entity);
  277. if (entity != null)
  278. {
  279. entity.RuleId = actionRequest.Id;
  280. entitys.Add(entity);
  281. }
  282. });
  283. entitys.ToUpdate(_sessionContext);
  284. await _tagQuestionRepository.ValidateUpdateAsync(entitys, cancellationToken);
  285. return entitys;
  286. }
  287. /// <summary>
  288. /// 修改规则标签
  289. /// </summary>
  290. /// <param name="actionRequest"></param>
  291. /// <param name="cancellationToken"></param>
  292. /// <returns></returns>
  293. /// <exception cref="NotImplementedException"></exception>
  294. private async Task<List<ExamRuleTag>> ModifyRuleTags(UpdateExtractRuleDto actionRequest, CancellationToken cancellationToken)
  295. {
  296. var ruleId = actionRequest.Id;
  297. if (actionRequest.RuleTagDtos == null) return null;
  298. //var all = await _ruleTagRepository.Queryable().Where(x => x.RuleId == actionRequest.Id).ToListAsync();
  299. //actionRequest.RuleTagDtos.ResolveOperationStatus(all);
  300. var ruleTags = new List<ExamRuleTag>();
  301. var entityQueyRequest = ExpressionableUtility.CreateExpression<ExamRuleTag>()
  302. .AndIF(ruleId.IsNotNullOrEmpty(), x => x.RuleId == ruleId).ToEntityQueryRequest<ExamRuleTag>();
  303. await DeleteRuleTags(entityQueyRequest, cancellationToken);
  304. ruleTags.AddRangeExt(await AddRuleTags(_addExtractRuleDto, cancellationToken));
  305. //ruleTags.AddRangeExt(await UpdateRuleTags(actionRequest, cancellationToken));
  306. //var ruleTagDtos = actionRequest.RuleTagDtos.Where(x => x.OperationStatus == EEOperationStatus.Delete).ToList();
  307. //var ids = ruleTagDtos.Select(x => x.Id).ToList();
  308. //var entityQueyRequest = ExpressionableUtility.CreateExpression<RuleTag>()
  309. // .AndIF(ids.IsNotNull(), x => ids.Contains(x.Id)).ToEntityQueryRequest<RuleTag>();
  310. return ruleTags;
  311. }
  312. private async Task<List<ExamRuleTag>> UpdateRuleTags(UpdateExtractRuleDto actionRequest, CancellationToken cancellationToken)
  313. {
  314. if (actionRequest.RuleTagDtos == null) return null;
  315. var ruleTagDtos = actionRequest.RuleTagDtos.Where(x => x.OperationStatus == EEOperationStatus.Update).ToList();
  316. var ids = ruleTagDtos.Select(x => x.Id).ToList();
  317. var ruleTags = await _ruleTagRepository.Queryable().Where(x => ids.Contains(x.Id)).ToListAsync();
  318. var entitys = new List<ExamRuleTag>();
  319. ruleTagDtos.ForEach(x =>
  320. {
  321. var entity = ruleTags.FirstOrDefault(x => x.Id == x.Id);
  322. entity = _mapper.Map(x, entity);
  323. if (entity != null)
  324. {
  325. entity.RuleId = actionRequest.Id;
  326. entitys.Add(entity);
  327. }
  328. });
  329. entitys.ToUpdate(_sessionContext);
  330. await _ruleTagRepository.ValidateUpdateAsync(entitys, cancellationToken);
  331. return entitys;
  332. }
  333. /// <summary>
  334. /// 删除规则标签
  335. /// </summary>
  336. /// <param name="tempEntityQueryRequest"></param>
  337. /// <param name="cancellationToken"></param>
  338. /// <returns></returns>
  339. private async Task DeleteRuleTags(EntityQueryRequest tempEntityQueryRequest, CancellationToken cancellationToken)
  340. {
  341. await _ruleTagRepository.DeleteWithValidateAsync(tempEntityQueryRequest, cancellationToken);
  342. }
  343. /// <summary>
  344. /// 删除标签试题数
  345. /// </summary>
  346. /// <param name="tempEntityQueryRequest"></param>
  347. /// <param name="cancellationToken"></param>
  348. /// <returns></returns>
  349. private async Task DeleteTagQuestions(EntityQueryRequest tempEntityQueryRequest, CancellationToken cancellationToken)
  350. {
  351. await _tagQuestionRepository.DeleteWithValidateAsync(tempEntityQueryRequest, cancellationToken);
  352. }
  353. /// <summary>
  354. /// 获取规则标签
  355. /// </summary>
  356. /// <param name="entityQueryRequest"></param>
  357. /// <returns></returns>
  358. /// <exception cref="NotImplementedException"></exception>
  359. private async Task<List<RuleTagDto>> GetRuleTagDtos(EntityQueryRequest entityQueryRequest)
  360. {
  361. var ruleTagTable = _ruleTagRepository.Queryable().Where(x => x.RuleId == entityQueryRequest.Id);
  362. var examTagTable = new ExamRepository<ExamTag>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
  363. var queryable = ruleTagTable.LeftJoin(examTagTable, (r, e) => r.TagId == e.Id).Select((r, e) => new RuleTagDto
  364. {
  365. Id = r.Id,
  366. TagId = r.TagId,
  367. Tag = e.Name
  368. });
  369. return await queryable.ToListAsync();
  370. }
  371. /// <summary>
  372. /// 获取标签试题数
  373. /// </summary>
  374. /// <param name="entityQueryRequest"></param>
  375. /// <returns></returns>
  376. /// <exception cref="NotImplementedException"></exception>
  377. private async Task<List<TagQuestionDto>> GetTagQuestions(EntityQueryRequest entityQueryRequest)
  378. {
  379. var tagQuestionTable = _tagQuestionRepository.Queryable().Where(x => x.RuleId == entityQueryRequest.Id);
  380. var examTagTable = new ExamRepository<ExamTag>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
  381. var tagQuestionDtos = tagQuestionTable.LeftJoin(examTagTable, (t, e) => t.TagId == e.Id).Select((t, e) => new TagQuestionDto
  382. {
  383. Id = t.Id,
  384. TagId = t.TagId,
  385. QuestionType = t.QuestionType,
  386. Count = t.Count,
  387. Tag = e.Name
  388. });
  389. return await tagQuestionDtos.ToListAsync();
  390. }
  391. /// <summary>
  392. /// 处理抽题规则Id
  393. /// </summary>
  394. /// <param name="actionRequest"></param>
  395. /// <param name="id"></param>
  396. /// <exception cref="NotImplementedException"></exception>
  397. private void ResolveExtractRuleId(AddExtractRuleDto actionRequest, string id)
  398. {
  399. actionRequest.TagQuestionDtos.ForEach(x => x.RuleId = id);
  400. actionRequest.RuleTagDtos.ForEach(x => x.RuleId = id);
  401. }
  402. /// <summary>
  403. /// 处理抽题规则Id
  404. /// </summary>
  405. /// <param name="actionRequest"></param>
  406. /// <param name="id"></param>
  407. /// <exception cref="NotImplementedException"></exception>
  408. private void ResolveExtractRuleId(UpdateExtractRuleDto actionRequest, string id)
  409. {
  410. actionRequest.TagQuestionDtos.ForEach(x => x.RuleId = id);
  411. actionRequest.RuleTagDtos.ForEach(x => x.RuleId = id);
  412. }
  413. private async Task<List<TagQuestionViewResponse>> GetTagQuestionCountAsync(TagQuestionRequest tagQuestionRequest)
  414. {
  415. var expression = tagQuestionRequest.GetExpression();
  416. var questionTagTable = new ExamRepository<ExamQuestionTag>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable().Where(expression);
  417. var questionTable = new ExamRepository<ExamQuestion>(_uow, _dataPermissionFilterBuilder, _serviceProvider).Queryable();
  418. var queryable = questionTagTable.LeftJoin(questionTable, (t, q) => t.QuestionId == q.Id)
  419. .GroupBy((t, q) => new { t.TagId, q.QuestionType })
  420. .OrderBy((t, q) => t.TagId)
  421. .Select((t, q) => new TagQuestionViewResponse
  422. {
  423. TagId = t.TagId,
  424. QuestionType = q.QuestionType,
  425. TotalCount = SqlFunc.AggregateCount(q.Id != null)
  426. });
  427. return await queryable.ToListAsync();
  428. }
  429. #endregion
  430. }
  431. }