public JsonResult AddMany(long userId, List <UserKnowledgeItem> knowledgeItems) { IUserKnowledgeQuery userKnowledgeQuery = CreateUserKnowledgeQuery(userId); if (EnumerableValidator.IsNullOrEmpty(knowledgeItems) || knowledgeItems.Any(userKnowledgeQuery.IsInvalid)) { LoggerWrapper.LogTo(LoggerName.Errors).ErrorFormat( "KnowledgeController.AddMany пользователь с идентификатором {0}, передал некорректные данные", userId); return(JsonResultHelper.Error(INVALID_DATA)); } List <KnowledgeAddStatus> statuses = userKnowledgeQuery.Add(knowledgeItems, MAX_COUNT_ITEMS_PER_DAY); KnowledgeAddStatus summaryStatus = EnumerableValidator.IsCountEquals(statuses, knowledgeItems) ? GetSummaryStatus(statuses) : KnowledgeAddStatus.Error; if (summaryStatus == KnowledgeAddStatus.Ok) { return(JsonResultHelper.Success(true)); } if (summaryStatus == KnowledgeAddStatus.ReachMaxLimit) { LoggerWrapper.LogTo(LoggerName.Errors).ErrorFormat( "KnowledgeController.AddMany пользователь с идентификатором {0}, достиг лимит данных за сегодня", userId); return(JsonResultHelper.Error( string.Format( "Сегодня вы уже добавили максимальное количество данных на обучение. В день вы можете добавлять не более {0} порций знаний. Завтра Вы вновь сможете добавлять новые элементы, а пока, рекомендуем изучить сегодняшний материал.", MAX_COUNT_ITEMS_PER_DAY))); } if (summaryStatus == KnowledgeAddStatus.AlreadyExists) { LoggerWrapper.LogTo(LoggerName.Errors).ErrorFormat( "KnowledgeController.AddMany пользователь с идентификатором {0}, уже добавлял данные", userId); return(JsonResultHelper.Error("Ранее вы уже добавляли эти данные на обучение.")); } LoggerWrapper.LogTo(LoggerName.Errors).ErrorFormat( "KnowledgeController.AddMany. Для пользователя с идентификатором {0} не удалось добавить данные, какая-то ошибка!", userId); return (JsonResultHelper.Error("Не удалось добавить порцию знаний! Попробуйте позже.")); }
private static bool HasAddStatus(IEnumerable <KnowledgeAddStatus> statuses, KnowledgeAddStatus knowledgeAddStatus) { return(statuses.Any(e => e == knowledgeAddStatus)); }
/// <summary> /// Добавляет "новые пункты знаний" пользователю /// </summary> /// <param name="knowledgeItems">новые пункты знаний</param> /// <param name="maxCountItemsPerDay">максимальное кол-во записей в день на добавление</param> /// <returns>список статусов добавления пунктов, для каждого пункта свой статус</returns> public List <KnowledgeAddStatus> Add(List <UserKnowledgeItem> knowledgeItems, int maxCountItemsPerDay) { var result = new List <KnowledgeAddStatus>(); Adapter.ActionByContext(c => { //очистить данные, т.к. в случае ошибки этот метод вызовется еще раз, а коллекции будут заполнены от предыдущей итерации result.Clear(); var uniqueHashes = new HashSet <string>(); var entitiesToSave = new List <Tuple <UserKnowledgeItem, UserKnowledge> >(); bool canAdd = CanAdd(maxCountItemsPerDay, c); if (!canAdd) { result.AddRange(Enumerable.Repeat(KnowledgeAddStatus.ReachMaxLimit, knowledgeItems.Count)); return; } foreach (UserKnowledgeItem knowledgeItem in knowledgeItems) { string hash = GetUniqueHash(knowledgeItem); if (uniqueHashes.Contains(hash)) { //с таким хэшем уже был в этой пачке - не пробовать сохранять - считаем, что уже сохранен result.Add(KnowledgeAddStatus.AlreadyExists); continue; } Tuple <KnowledgeAddStatus, UserKnowledge> statusWithEntity = ConvertItemToEntity(hash, knowledgeItem, c); uniqueHashes.Add(hash); KnowledgeAddStatus statusBeforeSave = statusWithEntity.Item1; if (statusBeforeSave == KnowledgeAddStatus.Ok) { entitiesToSave.Add(new Tuple <UserKnowledgeItem, UserKnowledge>(knowledgeItem, statusWithEntity.Item2)); } else { result.Add(statusBeforeSave); } } c.SaveChanges(); foreach (var pairToSave in entitiesToSave) { KnowledgeAddStatus status; if (IdValidator.IsValid(pairToSave.Item2.Id)) { status = KnowledgeAddStatus.Ok; } else { status = KnowledgeAddStatus.Error; LoggerWrapper.LogTo(LoggerName.Errors).ErrorFormat( "UserKnowledgeQuery.Add не удалось добавить пользователю с идентификатором {0} для языка {1} новый пункт знаний {2}", _userId, _languageId, KnowledgeToLogString(pairToSave.Item1)); } result.Add(status); } }); return(result); }