private async Task ImportFromDocument(IDocumentGenerator documentGenerator, string path, IReadOnlyCollection <string> selectedCultures, IReadOnlyCollection <Project> selectedProjects, IStatusProgress progress, CancellationToken cancellationToken) { IReadOnlyList <ResGroupModel <ResExcelModel> > data = await documentGenerator.ImportFromDocumentAsync <ResExcelModel>(path, progress, cancellationToken); progress.Report(StatusRes.GettingProjectsResources); SolutionResources resources = await GetSolutionResourcesAsync(selectedCultures, selectedProjects, progress, cancellationToken); progress.Report(StatusRes.MergingResources); var projectsJoin = resources.ProjectResources .Join(data, projRes => projRes.ProjectName, excelProjRes => excelProjRes.GroupTitle, (projRes, excelProjRes) => new { ProjRes = projRes, ExcelProjRes = excelProjRes }); foreach (var project in projectsJoin) { var resourceTablesJoin = project.ProjRes.Resources .Join(project.ExcelProjRes.Tables, resTable => resTable.Key, excelResTable => excelResTable.TableTitle, (resTable, excelResTable) => new { ResTable = resTable, ExcelResTable = excelResTable }); foreach (var resource in resourceTablesJoin) { int columnsCount = resource.ExcelResTable.Header.Columns.Count; int culturesCount = columnsCount - 2; List <string> cultureIds = resource.ExcelResTable.Header.Columns .Skip(1) .Select(col => col.Title == InvariantCultureDisplayName ? InvariantCultureId : CultureInfo.GetCultureInfo(col.Title).Name) .Take(culturesCount) .ToList(); List <string> resourceKeys = resource.ExcelResTable.Rows.Select(row => row.DataList[0].DataString).ToList(); List <string> comments = resource.ExcelResTable.Rows.Select(row => row.DataList[columnsCount - 1].DataString).ToList(); Dictionary <string, IReadOnlyCollection <ResourceEntryData> > excelResources = cultureIds .Select((cultureId, index) => new KeyValuePair <string, IReadOnlyCollection <ResourceEntryData> > ( cultureId, resourceKeys.Zip( resource.ExcelResTable.Rows.Select(row => row.DataList[index + 1].DataString), (key, value) => new { Key = key, Value = value }) .Zip(comments, (kvp, comment) => new ResourceEntryData(kvp.Key, kvp.Value, comment)) .ToList() )) .ToDictionary(kvp => kvp.Key, kvp => kvp.Value); var resourceFileTablesJoin = resource.ResTable.Value .Join(excelResources, resData => resData.Key, excelResData => excelResData.Key, (resData, excelResData) => new { ResData = resData.Value, ExcelResData = excelResData.Value }); foreach (var resFileTablesJoin in resourceFileTablesJoin) { try { UpdateResourceFile(resFileTablesJoin.ResData, resFileTablesJoin.ExcelResData); } catch (MissingManifestResourceException ex) { throw new MissingManifestResourceException(String.Format(ErrorsRes.MissingResourcesFormat, project.ProjRes.ProjectId, resFileTablesJoin.ResData.ResourceName, resFileTablesJoin.ResData.Culture.DisplayName), ex); } } } } }