public ImportResult Import(Core.Import import, IImportSource source, bool save) { var result = new ImportResult { Date = DateTime.UtcNow, File = import.Location, Type = import.Type.ToString() }; try { // build columns result.Step = ImportStep.BuildLayout; var layout = import.Columns.Select(x => String.IsNullOrEmpty(x.Target) ? (TEnum)Enum.Parse(typeof(TEnum), "None") : (TEnum)Enum.Parse(typeof(TEnum), x.Target) ).ToArray(); result.Layout = layout.Select(x => x.ToString()).ToArray(); // get data types var types = layout.Select(x => GetColumnType(x)).ToArray(); // validate layout result.Step = ImportStep.ValidateLayout; var layoutValid = ValidateLayout(layout); if (!layoutValid.Success) { layoutValid.Problems.Each(x => result.AddProblem(x)); return(result); } // convert all row data result.Step = ImportStep.ConvertRowData; var rows = source.Select(data => new ImportRow(data, types, layout)).ToList(); if (rows.Any(x => !x.IsValid)) { FillRowResults(result, rows); result.AddProblem("Some data could not be converted to the correct format. See row-by-row results for specific problems."); return(result); } // find existing rows result.Step = ImportStep.FindRowEntities; Parallel.ForEach(rows, r => r.Entity = Find(r)); // create missing rows result.Step = ImportStep.CreateRowEntities; Parallel.ForEach( rows.Where(x => null == x.Entity), r => { r.Entity = Create(r); r.IsNew = true; }); // validate all row data result.Step = ImportStep.ValidateRows; foreach (var r in rows) { ValidateRow(r); } // apply all row values result.Step = ImportStep.ImportRows; Parallel.ForEach(rows, r => Apply(r.Entity, r)); if (rows.Any(x => !x.IsValid)) { FillRowResults(result, rows); result.AddProblem("Some data could not be imported into the system. See row-by-row results for specific problems."); return(result); } // save all records if (save) { result.Step = ImportStep.SaveRows; Parallel.ForEach(rows, r => { try { Save(r.Entity); } catch (CouchException ex) { if (ex.Status == (int)HttpStatusCode.Conflict) { // conflicts typically occur when a unique id is supplied for two or more // new rows in an import sheet.. i.e. product id 1234 appears twice, and is new r.AddProblem( @"There was a conflict saving this record, typically because a unique was duplicated in the spreadsheet."); } else { throw; } } }); } Completed(); FillRowResults(result, rows); result.Step = ImportStep.Complete; result.Success = true; } catch (Exception ex) { result.AddProblem(String.Format("ERROR: Import encountered an unexpected error, proces aborted.<br/>Error: {0}<br />Stack: {1}.", (ex.InnerException ?? ex).Message, (ex.InnerException ?? ex).StackTrace)); if (result.Step == ImportStep.SaveRows) { result.AddProblem("DANGER: An error occurred DURING the Save step, meaning that some rows may have been written to the database, and some not. Re-importing this sheet could cause duplication of data."); } } return(result); }