Exemplo n.º 1
0
        /// <summary>
        /// Recursive function that parses a single data row (string array) into 0 or more entities that are each
        /// added in the correct list in the <see cref="MappingInfo"/> tree. Any errors will be added to the <see cref="ImportErrors"/>.
        /// Entities referenced by user keys should be loaded in advance and passed to this function as a <see cref="RelatedEntities"/> dictionary.
        /// This function is the opposite of <see cref="DataComposer.ComposeDataRowsFromEntity(List{string[]}, EntityWithKey, MappingInfo, int, int)"/>
        /// </summary>
        /// <param name="dataRow">An array of strings representing a single row in a CSV or XSLX file</param>
        /// <param name="rowNumber">The number of the current row, for the purpose of error reporting</param>
        /// <param name="mapping">The <see cref="MappingInfo"/> to rely on for constructing the <see cref="Entity"/> objects</param>
        /// <param name="entities">All related entities that are referenced by user keys in the raw data</param>
        /// <param name="errors">Any validation errors are added to this collection</param>
        /// <returns>False if the <see cref="ImportErrors"/> dictionary has been maxed out, true otherwise.</returns>
        private bool ParseRow(string[] dataRow, int rowNumber, MappingInfo mapping, RelatedEntities entities, ImportErrors errors, int selfRefPropertiesCount = 0)
        {
            bool entityCreated = false;

            foreach (var prop in mapping.SimpleProperties)
            {
                var stringField = dataRow[prop.Index];
                if (!string.IsNullOrEmpty(stringField))
                {
                    if (!entityCreated)
                    {
                        mapping.Entity = mapping.CreateBaseEntity(rowNumber);
                        mapping.List.Add(mapping.Entity);
                        entityCreated = true;
                    }

                    var entity = prop.GetTerminalEntityForSave(mapping.Entity);

                    // Hydrate the property
                    if (prop is ForeignKeyMappingInfo fkProp && fkProp.NotUsingIdAsKey)
                    {
                        // Get the user key value (usually the code or the name)
                        object userKeyValue = fkProp.KeyType switch
                        {
                            KeyType.String => stringField?.Trim(),
                            KeyType.Int => int.Parse(stringField),
                            _ => null
                        };

                        // Get the entity from the dictionary
                        var dic = entities[(fkProp.TargetType, fkProp.TargetDefId, fkProp.KeyPropertyMetadata.Descriptor.Name)];