Exemplo n.º 1
0
        /// <summary>
        /// Takes an <see cref="IEnumerable{T}"/> of string arrays representing the raw data of the imported file.
        /// Then using the specifications in the <see cref="MappingInfo"/> it translates this raw data into an
        /// <see cref="IEnumerable{T}"/> of entities. Any problems will be added in the <see cref="ImportErrors"/> dictionary.
        /// This function is the opposite of <see cref="DataComposer.Compose{TEntityForSave}(List{TEntityForSave}, MappingInfo)"/>.
        /// </summary>
        public async Task <IEnumerable <TEntityForSave> > ParseAsync <TEntityForSave>(IEnumerable <string[]> dataWithoutHeader, MappingInfo mapping, ImportErrors errors)
            where TEntityForSave : Entity
        {
            // Load related entities from API
            var relatedEntities = await LoadRelatedEntities(dataWithoutHeader, mapping, errors);

            if (!errors.IsValid)
            {
                return(null);
            }

            // Clear all cached entities and lists, and create the root list
            mapping.ClearEntitiesAndLists();
            mapping.List = new List <TEntityForSave>(); // This root list will contain the final result

            // Set some values on the root mapping infor for handling self referencing FKs
            mapping.IsRoot = true;
            int matchesIndex = 0;

            foreach (var prop in mapping.SimpleProperties.OfType <ForeignKeyMappingInfo>().Where(p => p.IsSelfReferencing))
            {
                prop.EntityMetadataMatchesIndex = matchesIndex++;
            }

            int rowNumber = 2;

            foreach (var dataRow in dataWithoutHeader)                                                         // Foreach row
            {
                bool keepGoing = ParseRow(dataRow, rowNumber, mapping, relatedEntities, errors, matchesIndex); // Recursive function
                if (!keepGoing)
                {
                    // This means the errors collection is full, no need to keep going
                    break;
                }

                rowNumber++;
            }

            // Grab the result from the root mapping
            var result = mapping.List.Cast <TEntityForSave>();

            // Hydrate self referencing FKs if any, these properties are not hydrated in ParseRow()
            // Since they requires all the imported entities to be created and all their other
            // properties already hydrated
            HydrateSelfReferencingForeignKeys(result, mapping, errors);

            // Return the result
            return(result);
        }