public async Task <bool> Insert(ProductAggregate productAggregate) { if (productAggregate == null) { throw new ArgumentNullException(nameof(productAggregate)); } using (var transaction = await _context.Database.BeginTransactionAsync().ConfigureAwait(false)) { try { var record = productAggregate.ToModel(); var tags = new List <Models.ProductTag>(); if (productAggregate.Tags != null && productAggregate.Tags.Any()) // Add tags { var tagNames = productAggregate.Tags; var connectedTags = _context.Tags.Where(t => tagNames.Any(tn => t.Name == tn)); foreach (var connectedTag in connectedTags) { tags.Add(new Models.ProductTag { Id = Guid.NewGuid().ToString(), TagName = connectedTag.Name, ProductId = productAggregate.Id }); } var connectedTagNames = (await connectedTags.Select(t => t.Name).ToListAsync().ConfigureAwait(false)); foreach (var notExistingTagName in tagNames.Where(tn => !connectedTagNames.Contains(tn))) { var newTag = new Models.Tag { Name = notExistingTagName, Description = notExistingTagName }; _context.Tags.Add(newTag); tags.Add(new Models.ProductTag { Id = Guid.NewGuid().ToString(), TagName = notExistingTagName, ProductId = productAggregate.Id, Tag = newTag }); } } if (productAggregate.Filters != null && productAggregate.Filters.Any()) // Add filters { var ids = productAggregate.Filters.Select(f => f.FilterValueId); var filters = await _context.FilterValues.Where(f => ids.Contains(f.Id)).Select(f => new Models.ProductFilter { Id = Guid.NewGuid().ToString(), FilterValueId = f.Id, ProductId = productAggregate.Id }).ToListAsync().ConfigureAwait(false); record.Filters = filters; } if (productAggregate.PartialImagesUrl != null && productAggregate.PartialImagesUrl.Any()) // Add images { record.Images = productAggregate.PartialImagesUrl.Select(i => new Models.ProductImage { Id = Guid.NewGuid().ToString(), PartialPath = i } ).ToList(); } record.Tags = tags; _context.Products.Add(record); await _context.SaveChangesAsync().ConfigureAwait(false); transaction.Commit(); return(true); } catch { transaction.Rollback(); return(false); } } }
public async Task <ProductAggregate> Process(Stream csvStream) { var streamReader = new StreamReader(csvStream); List <string> lines = new List <string>(); while (!streamReader.EndOfStream) { lines.Add(await streamReader.ReadLineAsync()); } var headers = lines.Take(1).SelectMany(a => a.Split(',')).ToArray(); var values = lines.Skip(1).ToArray(); var productTemplateDictionary = new Dictionary <string, int>(); var productCatalogDictionary = new Dictionary <string, int>(); var productDetailsDictionary = new Dictionary <string, int>(); var productCatalogs = new List <ProductCatalog>(); var productTemplates = new List <ProductTemplate>(); var productCatalogType = typeof(ProductCatalog); var productTemplateType = typeof(ProductCatalog); for (int i = 0; i < headers.Count(); i++) { if (productCatalogType.GetProperties().Any(prop => prop.Name == headers[i])) { productCatalogDictionary.Add(headers[i], i); } if (productTemplateType.GetProperties().Any(prop => prop.Name == headers[i])) { productTemplateDictionary.Add(headers[i], i); } if (productTemplateType.GetProperties().All(prop => prop.Name != headers[i]) && productCatalogType.GetProperties().All(prop => prop.Name != headers[i])) { productDetailsDictionary.Add(headers[i], i); } } var productTemplateGroup = new HashSet <string>(); for (int i = 0; i < values.Length; i++) { var extraFields = new Dictionary <string, string>(); var line = values[i]; var cells = Regex.Split(line, ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)"); if (productTemplateGroup.Contains(cells[productTemplateDictionary["Id"]])) { var productCatalog = new ProductCatalog(); productCatalog.ProductTemplateId = int.Parse(cells[productTemplateDictionary["Id"]]); productCatalog.Id = i + 1; productCatalog.Name = cells[productCatalogDictionary["Name"]]; productCatalog.Price = cells[productCatalogDictionary["Price"]]; productCatalog.Tags = cells[productCatalogDictionary["Tags"]]; foreach (var item in productDetailsDictionary) { if (!string.IsNullOrEmpty(cells[productDetailsDictionary[item.Key]])) { extraFields.Add(item.Key, cells[productDetailsDictionary[item.Key]]); } } productCatalog.Details = JsonSerializer.Serialize(extraFields); productCatalogs.Add(productCatalog); } else { var productCatalog = new ProductCatalog(); var productTemplate = new ProductTemplate(); productTemplateGroup.Add(cells[productTemplateDictionary["Id"]]); productTemplate.Id = int.Parse(cells[productTemplateDictionary["Id"]]); productTemplate.Name = cells[productTemplateDictionary["Name"]]; productCatalog.Id = i + 1; productCatalog.ProductTemplateId = productTemplate.Id; productCatalog.Name = cells[productCatalogDictionary["Name"]]; productCatalog.Price = cells[productCatalogDictionary["Price"]]; productCatalog.Tags = cells[productCatalogDictionary["Tags"]]; foreach (var item in productDetailsDictionary) { if (!string.IsNullOrEmpty(cells[productDetailsDictionary[item.Key]])) { extraFields.Add(item.Key, cells[productDetailsDictionary[item.Key]]); } } productTemplates.Add(productTemplate); productCatalog.Details = JsonSerializer.Serialize(extraFields); productCatalogs.Add(productCatalog); } } var aggregate = new ProductAggregate { ProductTemplates = productTemplates, ProductCatalogs = productCatalogs }; return(await Task.FromResult(aggregate)); }