using System; using System.Collections.Generic; using System.Linq; using AudibleApi.Common; using AudibleUtilities; using DataLayer; using Dinah.Core.Collections.Generic; namespace DtoImporterService { public class CategoryImporter : ItemsImporterBase { protected override IValidator Validator => new CategoryValidator(); private Dictionary CategoryCache { get; set; } = new(); public HashSet LadderCache { get; private set; } = new(); public CategoryImporter(LibationContext context) : base(context) { } protected override int DoImport(IEnumerable importItems) { // load db existing => .Local loadLocal_categories(); // upsert var categoryLadders = importItems .SelectMany(i => i.DtoItem.CategoryLadders) .Select(cl => cl.Ladder) .Where(l => l?.Length > 0) .ToList(); var qtyNew = upsertCategories(categoryLadders); return qtyNew; } private void loadLocal_categories() { // load existing => local LadderCache = DbContext.GetCategoryLadders().ToHashSet(); CategoryCache = LadderCache.SelectMany(cl => cl.Categories).ToDictionarySafe(c => c.AudibleCategoryId); } // only use after loading contributors => local private int upsertCategories(List ladders) { var qtyNew = 0; foreach (var ladder in ladders) { var categories = new List(ladder.Length); for (var i = 0; i < ladder.Length; i++) { var id = ladder[i].CategoryId; var name = ladder[i].CategoryName; if (!CategoryCache.TryGetValue(id, out var category)) { category = addCategory(id, name); } categories.Add(category); } var categoryLadder = new DataLayer.CategoryLadder(categories); if (!LadderCache.Contains(categoryLadder)) { addCategoryLadder(categoryLadder); qtyNew++; } } return qtyNew; } private DataLayer.CategoryLadder addCategoryLadder(DataLayer.CategoryLadder categoryList) { try { var entityEntry = DbContext.CategoryLadders.Add(categoryList); var entity = entityEntry.Entity; LadderCache.Add(entity); return entity; } catch (Exception ex) { Serilog.Log.Logger.Error(ex, "Error adding category ladder. {@DebugInfo}", categoryList); throw; } } private Category addCategory(string id, string name) { try { var category = new Category(new AudibleCategoryId(id), name); var entityEntry = DbContext.Categories.Add(category); var entity = entityEntry.Entity; CategoryCache.Add(entity.AudibleCategoryId, entity); return entity; } catch (Exception ex) { Serilog.Log.Logger.Error(ex, "Error adding category. {@DebugInfo}", new { id, name }); throw; } } } }