Exemple #1
0
        public CsvProductMap(CsvProductMappingConfiguration mappingCfg)
        {
            //Dynamical map scalar product fields use by manual mapping information
            foreach (var mappingItem in mappingCfg.PropertyMaps.Where(x => !string.IsNullOrEmpty(x.CsvColumnName) || !string.IsNullOrEmpty(x.CustomValue)))
            {
                var propertyInfo = typeof(CsvProduct).GetProperty(mappingItem.EntityColumnName);
                if (propertyInfo != null)
                {
                    var newMap = new CsvPropertyMap(propertyInfo);
                    newMap.TypeConverterOption(CultureInfo.InvariantCulture);
                    newMap.TypeConverterOption(NumberStyles.Any);
                    newMap.TypeConverterOption(true, "yes", "true");
                    newMap.TypeConverterOption(false, "false", "no");
                    if (!string.IsNullOrEmpty(mappingItem.CsvColumnName))
                    {
                        //Map fields if mapping specified
                        newMap.Name(mappingItem.CsvColumnName);
                    }
                    //And default values if it specified
                    if (mappingItem.CustomValue != null)
                    {
                        var typeConverter = TypeDescriptor.GetConverter(propertyInfo.PropertyType);
                        newMap.Default(typeConverter.ConvertFromString(mappingItem.CustomValue));
                    }
                    PropertyMaps.Add(newMap);
                }
            }

            //Map properties
            if (mappingCfg.PropertyCsvColumns != null && mappingCfg.PropertyCsvColumns.Any())
            {
                // Exporting multiple csv fields from the same property (which is a collection)
                foreach (var propertyCsvColumn in mappingCfg.PropertyCsvColumns)
                {
                    // create CsvPropertyMap manually, because this.Map(x =>...) does not allow
                    // to export multiple entries for the same property
                    var csvPropertyMap = new CsvPropertyMap(typeof(CsvProduct).GetProperty("PropertyValues"));
                    csvPropertyMap.Name(propertyCsvColumn);

                    // create custom converter instance which will get the required record from the collection
                    csvPropertyMap.UsingExpression <ICollection <coreModel.PropertyValue> >(null, propValues =>
                    {
                        var propValue = propValues.FirstOrDefault(x => x.PropertyName == propertyCsvColumn);
                        if (propValue != null)
                        {
                            return(propValue.Value != null ? propValue.Value.ToString() : string.Empty);
                        }
                        return(string.Empty);
                    });

                    PropertyMaps.Add(csvPropertyMap);
                }

                var newPropMap = new CsvPropertyMap(typeof(CsvProduct).GetProperty("PropertyValues"));
                newPropMap.UsingExpression <ICollection <coreModel.PropertyValue> >(null, null).ConvertUsing(x => mappingCfg.PropertyCsvColumns.Select(column => new coreModel.PropertyValue {
                    PropertyName = column, Value = x.GetField <string>(column)
                }).ToList());
                PropertyMaps.Add(newPropMap);
            }
        }
Exemple #2
0
        public void AutoMap(IEnumerable <string> csvColumns)
        {
            CsvColumns = csvColumns.ToArray();

            foreach (var propertyMap in PropertyMaps)
            {
                var entityColumnName     = propertyMap.EntityColumnName;
                var betterMatchCsvColumn = csvColumns.Select(x => new { csvColumn = x, distance = x.ComputeLevenshteinDistance(entityColumnName) })
                                           .Where(x => x.distance < 2)
                                           .OrderBy(x => x.distance)
                                           .Select(x => x.csvColumn)
                                           .FirstOrDefault();
                if (betterMatchCsvColumn != null)
                {
                    propertyMap.CsvColumnName = betterMatchCsvColumn;
                    propertyMap.CustomValue   = null;
                }
                else
                {
                    propertyMap.CsvColumnName = null;
                }
            }

            //All not mapped properties may be a product property
            PropertyCsvColumns = csvColumns.Except(PropertyMaps.Where(x => x.CsvColumnName != null).Select(x => x.CsvColumnName)).ToArray();
            //Generate ETag for identifying csv format
            ETag = string.Join(";", CsvColumns).GetMD5Hash();
        }
Exemple #3
0
        public virtual CsvPropertyMap PropertyMap <T>(Expression <Func <T, object> > expression)
        {
            var property       = ReflectionHelper.GetProperty(expression);
            var csvPropertyMap = PropertyMaps.SingleOrDefault(m =>
            {
                if (m.Data.Property == property)
                {
                    return(true);
                }
                if (m.Data.Property.Name != property.Name)
                {
                    return(false);
                }
                if (m.Data.Property.DeclaringType.IsAssignableFrom(property.DeclaringType))
                {
                    return(true);
                }
                return(property.DeclaringType.IsAssignableFrom(m.Data.Property.DeclaringType));
            });

            if (csvPropertyMap != null)
            {
                return(csvPropertyMap);
            }
            var maxIndex = new CsvPropertyMap(property);

            maxIndex.Data.Index = GetMaxIndex() + 1;
            PropertyMaps.Add(maxIndex);
            return(maxIndex);
        }
Exemple #4
0
 private void CheckForPropertyMap(Type typeKey)
 {
     if (!PropertyMaps.ContainsKey(typeKey))
     {
         PropertyMaps.Add(typeKey, new Dictionary <string, PropertyMappingExpression>());
     }
 }
Exemple #5
0
        public void Seal(IConfigurationProvider configurationProvider)
        {
            if (_sealed)
            {
                return;
            }
            _sealed = true;

            foreach (var includedMemberTypeMap in _includedMembersTypeMaps)
            {
                includedMemberTypeMap.TypeMap.Seal(configurationProvider);
                ApplyIncludedMemberTypeMap(includedMemberTypeMap);
            }
            foreach (var inheritedTypeMap in _inheritedTypeMaps)
            {
                ApplyInheritedTypeMap(inheritedTypeMap);
            }

            _orderedPropertyMaps = PropertyMaps.OrderBy(map => map.MappingOrder).ToArray();
            _propertyMaps.Clear();

            MapExpression = CreateMapperLambda(configurationProvider, null);

            Features.Seal(configurationProvider);
        }
Exemple #6
0
        /// <summary>
        /// Get the largest index for the
        /// properties/fields and references.
        /// </summary>
        /// <returns>The max index.</returns>
        public virtual int GetMaxIndex()
        {
            if (ParameterMaps.Count == 0 && PropertyMaps.Count == 0 && ReferenceMaps.Count == 0)
            {
                return(-1);
            }

            var indexes = new List <int>();

            if (ParameterMaps.Count > 0)
            {
                indexes.AddRange(ParameterMaps.Select(parameterMap => parameterMap.GetMaxIndex()));
            }

            if (PropertyMaps.Count > 0)
            {
                indexes.Add(PropertyMaps.Max(pm => pm.Data.Index));
            }

            if (ReferenceMaps.Count > 0)
            {
                indexes.AddRange(ReferenceMaps.Select(referenceMap => referenceMap.GetMaxIndex()));
            }

            return(indexes.Max());
        }
Exemple #7
0
        public void AddPropertyMap(MemberInfo destProperty, IEnumerable <MemberInfo> resolvers)
        {
            var propertyMap = new PropertyMap(destProperty, this);

            propertyMap.ChainMembers(resolvers);

            PropertyMaps.Add(propertyMap);
        }
Exemple #8
0
        public PropertyMap AddProperty(string property, string columnName)
        {
            var map = new PropertyMap(property, columnName);

            PropertyMaps.Add(map);

            return(map);
        }
Exemple #9
0
        /// <summary>
        /// Maps a non-member to a CSV field. This allows for writing
        /// data that isn't mapped to a class property/field.
        /// </summary>
        /// <returns>The property mapping.</returns>
        public virtual CsvPropertyMap Map()
        {
            var propertyMap = new CsvPropertyMap(null);

            propertyMap.Data.Index = GetMaxIndex() + 1;
            PropertyMaps.Add(propertyMap);

            return(propertyMap);
        }
        private void FillPropertyMaps()
        {
            foreach (var map in _propertyMaps)
            {
                PropertyMaps.Add(map);
            }

            foreach (var linqPropertyMap in _linqPropertyMaps)
            {
                LinqPropertyMaps.Add(linqPropertyMap);
            }
        }
Exemple #11
0
        /// <summary>
        /// Maps a property to a CSV field.
        /// </summary>
        /// <param name="expression">The property to map.</param>
        /// <returns>The property mapping.</returns>
        protected virtual CsvPropertyMap Map(Expression <Func <T, object> > expression)
        {
            var property = ReflectionHelper.GetProperty(expression);

            if (PropertyMaps.Any(m => m.Data.Property == property))
            {
                throw new CsvConfigurationException(string.Format("Property '{0}' has already been mapped.", property.Name));
            }
            var propertyMap = new CsvPropertyMap(property);

            PropertyMaps.Add(propertyMap);
            return(propertyMap);
        }
Exemple #12
0
        /// <summary>
        /// Get the largest index for the
        /// properties and references.
        /// </summary>
        /// <returns>The max index.</returns>
        internal int GetMaxIndex()
        {
            if (PropertyMaps.Count == 0 && ReferenceMaps.Count == 0)
            {
                return(IndexStart);
            }

            var indexes = new List <int> {
                PropertyMaps.Max(pm => pm.Data.Index)
            };

            indexes.AddRange(ReferenceMaps.Select(referenceMap => referenceMap.GetMaxIndex()));

            return(indexes.Max());
        }
Exemple #13
0
        public PropertyMap FindOrCreatePropertyMapFor(MemberInfo destinationProperty)
        {
            var propertyMap = GetExistingPropertyMapFor(destinationProperty);

            if (propertyMap != null)
            {
                return(propertyMap);
            }

            propertyMap = new PropertyMap(destinationProperty, this);

            PropertyMaps.Add(propertyMap);

            return(propertyMap);
        }
Exemple #14
0
        /// <summary>
        /// Maps a property to a CSV field.
        /// </summary>
        /// <param name="property">The property to map.</param>
        /// <returns>The property mapping.</returns>
        public virtual CsvPropertyMap Map(PropertyInfo property)
        {
            var existingMap = PropertyMaps.Find(property);

            if (existingMap != null)
            {
                return(existingMap);
            }

            var propertyMap = new CsvPropertyMap(property);

            propertyMap.Data.Index = GetMaxIndex() + 1;
            PropertyMaps.Add(propertyMap);

            return(propertyMap);
        }
        public RelationshipMap(string tblName)
        {
            var baseType = typeof(Entity);
            var props    = baseType.GetProperties();

            foreach (var p in props)
            {
                PropertyMaps.Add(new ManualPropertyMap
                {
                    CaseSensitive = true,
                    ColumnName    = $"{tblName}.{p.Name}",
                    Ignored       = false,
                    PropertyInfo  = p
                });
            }
        }
Exemple #16
0
        /// <summary>
        /// Creates and returns a <see cref="QueryMapDataModel"/> from the current <see cref="QueryMap"/>
        /// </summary>
        /// <returns></returns>
        public QueryMapDataModel ToDataModel() => new QueryMapDataModel()
        {
            Id          = Id,
            DatabaseId  = DatabaseOptions.Id,
            TableNames  = Tables.Select(x => x.TableName).ToArray(),
            Joins       = Joins.Select(x => x.ToDataModel()).ToArray(),
            Color       = Color,
            Description = Description,
            Name        = Name,

            // Set the column maps
            PropertyMaps = PropertyMaps.Select(x => x.ToDataModel()).ToArray(),

            // Set the data grid presenter maps
            DataGridPresenterMaps = DataGridPresenterMaps.Select(x => x.ToDataModel()).ToArray(),
        };
Exemple #17
0
        /// <summary>
        /// Maps a property to a Excel field.
        /// </summary>
        /// <param name="property">Property to map</param>
        /// <returns>The property mapping.</returns>
        private ExcelPropertyMap Map(
            PropertyInfo property)
        {
            var existingMap = PropertyMaps.SingleOrDefault(m => m.Data.Property == property);

            if (existingMap != null)
            {
                return(existingMap);
            }

            var propertyMap = new ExcelPropertyMap(property);

            propertyMap.Data.Index = GetMaxIndex() + 1;
            PropertyMaps.Add(propertyMap);

            return(propertyMap);
        }
Exemple #18
0
        /// <summary>
        ///     Get the largest index for the
        ///     properties and references.
        /// </summary>
        /// <returns>The max index.</returns>
        internal int GetMaxIndex()
        {
            if (PropertyMaps.Count == 0 && ReferenceMaps.Count == 0)
            {
                return(-1);
            }
            var nums = new List <int>();

            if (PropertyMaps.Count > 0)
            {
                nums.Add(PropertyMaps.Max(pm => pm.Data.Index));
            }
            nums.AddRange(
                from referenceMap in ReferenceMaps
                select referenceMap.GetMaxIndex());
            return(nums.Max());
        }
Exemple #19
0
        public PropertyMap GetExistingPropertyMapFor(MemberInfo destinationProperty)
        {
            if (!destinationProperty.DeclaringType.IsAssignableFrom(DestinationType))
            {
                return(null);
            }
            var propertyMap =
                PropertyMaps.FirstOrDefault(pm => pm.DestMember.Name.Equals(destinationProperty.Name));

            if (propertyMap != null)
            {
                return(propertyMap);
            }

            propertyMap =
                _inheritedMaps.FirstOrDefault(pm => pm.DestMember.Name.Equals(destinationProperty.Name));

            if (propertyMap == null)
            {
                return(null);
            }

            var propertyInfo = propertyMap.DestMember as PropertyInfo;

            if (propertyInfo == null)
            {
                return(propertyMap);
            }

            var baseAccessor = propertyInfo.GetMethod;

            if (baseAccessor.IsAbstract || baseAccessor.IsVirtual)
            {
                return(propertyMap);
            }

            var accessor = ((PropertyInfo)destinationProperty).GetMethod;

            if (baseAccessor.DeclaringType == accessor.DeclaringType)
            {
                return(propertyMap);
            }

            return(null);
        }
Exemple #20
0
        /// <summary>
        /// Maps a property to a CSV field.
        /// </summary>
        /// <param name="expression">The property to map.</param>
        /// <returns>The property mapping.</returns>
        protected virtual CsvPropertyMap Map(Expression <Func <T, object> > expression)
        {
            var property = ReflectionHelper.GetProperty(expression);

            var existingMap = PropertyMaps.SingleOrDefault(m => m.Data.Property == property);

            if (existingMap != null)
            {
                return(existingMap);
            }

            var propertyMap = new CsvPropertyMap(property);

            propertyMap.Data.Index = GetMaxIndex() + 1;
            PropertyMaps.Add(propertyMap);

            return(propertyMap);
        }
Exemple #21
0
        /// <summary>
        /// Maps a property/field to a CSV field.
        /// </summary>
        /// <param name="member">The property/field to map.</param>
        /// <param name="useExistingMap">If true, an existing map will be used if available.
        /// If false, a new map is created for the same property/field.</param>
        /// <returns>The property/field mapping.</returns>
        public virtual CsvPropertyMap Map(MemberInfo member, bool useExistingMap = true)
        {
            if (useExistingMap)
            {
                var existingMap = PropertyMaps.Find(member);
                if (existingMap != null)
                {
                    return(existingMap);
                }
            }

            var propertyMap = new CsvPropertyMap(member);

            propertyMap.Data.Index = GetMaxIndex() + 1;
            PropertyMaps.Add(propertyMap);

            return(propertyMap);
        }
        public string GetPropertyMappedFrom(string propertyName, Type typeFrom)
        {
            var mapFromProperty = propertyName;

            if (PropertyMaps.Any(pm => pm.Type2Property == propertyName &&
                                 pm.Type1 == typeFrom))
            {
                mapFromProperty = PropertyMaps.First(pm => pm.Type2Property == propertyName &&
                                                     pm.Type1 == typeFrom).Type1Property;
            }
            else if (PropertyMaps.Any(pm => pm.Type1Property == propertyName &&
                                      pm.Type2 == typeFrom))
            {
                mapFromProperty = PropertyMaps.First(pm => pm.Type1Property == propertyName &&
                                                     pm.Type2 == typeFrom).Type2Property;
            }
            return(mapFromProperty);
        }
Exemple #23
0
        /// <summary>
        /// Maps a property/field to a CSV field.
        /// </summary>
        /// <param name="classType">The type of the class this map is for. This may not be the same type
        /// as the member.DeclaringType or the current ClassType due to nested property mappings.</param>
        /// <param name="member">The property/field to map.</param>
        /// <param name="useExistingMap">If true, an existing map will be used if available.
        /// If false, a new map is created for the same property/field.</param>
        /// <returns>The property/field mapping.</returns>
        public CsvPropertyMap Map(Type classType, MemberInfo member, bool useExistingMap = true)
        {
            if (useExistingMap)
            {
                var existingMap = PropertyMaps.Find(member);
                if (existingMap != null)
                {
                    return(existingMap);
                }
            }

            var propertyMap = CsvPropertyMap.CreateGeneric(classType, member);

            propertyMap.Data.Index = GetMaxIndex() + 1;
            PropertyMaps.Add(propertyMap);

            return(propertyMap);
        }
Exemple #24
0
        public string[] GetUnmappedPropertyNames()
        {
            Func <PropertyMap, string> getFunc =
                pm =>
                ConfiguredMemberList == MemberList.Destination
                        ? pm.DestMember.Name
                        : pm.CustomExpression == null && pm.SrcMember != null
                            ? pm.SrcMember.Name
                            : pm.DestMember.Name;
            var autoMappedProperties = PropertyMaps.Where(pm => pm.IsMapped())
                                       .Select(getFunc).ToList();
            var inheritedProperties = _inheritedMaps.Where(pm => pm.IsMapped())
                                      .Select(getFunc).ToList();

            IEnumerable <string> properties;

            if (ConfiguredMemberList == MemberList.Destination)
            {
                properties = DestinationTypeDetails.PublicWriteAccessors
                             .Select(p => p.Name)
                             .Except(autoMappedProperties)
                             .Except(inheritedProperties);
            }
            else
            {
                var redirectedSourceMembers = PropertyMaps
                                              .Where(pm => pm.IsMapped() && pm.SrcMember != null && pm.SrcMember.Name != pm.DestMember.Name)
                                              .Select(pm => pm.SrcMember.Name);

                var ignoredSourceMembers = _sourceMemberConfigs
                                           .Where(smc => smc.IsIgnored())
                                           .Select(pm => pm.SourceMember.Name).ToList();

                properties = SourceTypeDetails.PublicReadAccessors
                             .Select(p => p.Name)
                             .Except(autoMappedProperties)
                             .Except(inheritedProperties)
                             .Except(redirectedSourceMembers)
                             .Except(ignoredSourceMembers);
            }

            return(properties.Where(memberName => !IgnorePropertiesStartingWith.Any(memberName.StartsWith)).ToArray());
        }
Exemple #25
0
        public void Seal(TypeMapRegistry typeMapRegistry, IConfigurationProvider configurationProvider)
        {
            if (_sealed)
            {
                return;
            }
            _sealed = true;

            foreach (var inheritedTypeMap in _inheritedTypeMaps)
            {
                ApplyInheritedTypeMap(inheritedTypeMap);
            }

            _orderedPropertyMaps =
                PropertyMaps
                .Union(_inheritedMaps)
                .OrderBy(map => map.MappingOrder).ToArray();

            //MapExpression = new TypeMapPlanBuilder(configurationProvider, typeMapRegistry, this).CreateMapperLambda();
        }
Exemple #26
0
        public virtual CsvPropertyMap PropertyMap <T>(Expression <Func <T, object> > expression)
        {
            var property    = ReflectionHelper.GetProperty(expression);
            var existingMap = PropertyMaps.SingleOrDefault(m =>
                                                           m.Data.Property == property ||
                                                           m.Data.Property.Name == property.Name &&
                                                           (m.Data.Property.DeclaringType.IsAssignableFrom(property.DeclaringType) || property.DeclaringType.IsAssignableFrom(m.Data.Property.DeclaringType)));

            if (existingMap != null)
            {
                return(existingMap);
            }

            var propertyMap = new CsvPropertyMap(property);

            propertyMap.Data.Index = GetMaxIndex() + 1;
            PropertyMaps.Add(propertyMap);

            return(propertyMap);
        }
Exemple #27
0
        private void ApplyInheritedTypeMap(TypeMap inheritedTypeMap)
        {
            foreach (var inheritedMappedProperty in inheritedTypeMap.PropertyMaps.Where(m => m.IsMapped))
            {
                var conventionPropertyMap = PropertyMaps
                                            .SingleOrDefault(m =>
                                                             m.DestinationName == inheritedMappedProperty.DestinationName);

                if (conventionPropertyMap != null)
                {
                    conventionPropertyMap.ApplyInheritedPropertyMap(inheritedMappedProperty);
                }
                else
                {
                    var propertyMap = new PropertyMap(inheritedMappedProperty, this);

                    _inheritedMaps.Add(propertyMap);
                }
            }

            //Include BeforeMap
            foreach (var beforeMapAction in inheritedTypeMap._beforeMapActions)
            {
                AddBeforeMapAction(beforeMapAction);
            }
            //Include AfterMap
            foreach (var afterMapAction in inheritedTypeMap._afterMapActions)
            {
                AddAfterMapAction(afterMapAction);
            }
            var notOverridenSourceConfigs =
                inheritedTypeMap._sourceMemberConfigs.Where(
                    baseConfig => _sourceMemberConfigs.All(derivedConfig => derivedConfig.SourceMember != baseConfig.SourceMember));

            _sourceMemberConfigs.AddRange(notOverridenSourceConfigs);
            var notOverridenPathMaps =
                inheritedTypeMap.PathMaps.Where(
                    baseConfig => PathMaps.All(derivedConfig => derivedConfig.MemberPath != baseConfig.MemberPath));

            _pathMaps.AddRange(notOverridenPathMaps);
        }
Exemple #28
0
        public string[] GetUnmappedPropertyNames()
        {
            var autoMappedProperties = GetPropertyNames(PropertyMaps);

            IEnumerable <string> properties;

            if (ConfiguredMemberList == MemberList.Destination)
            {
                properties = DestinationTypeDetails.PublicWriteAccessors
                             .Select(p => p.Name)
                             .Except(autoMappedProperties)
                             .Except(PathMaps.Select(p => p.MemberPath.First.Name));
            }
            else
            {
                var redirectedSourceMembers = PropertyMaps
                                              .Where(pm => pm.IsMapped && pm.SourceMember != null && pm.SourceMember.Name != pm.DestinationName)
                                              .Select(pm => pm.SourceMember.Name);

                var ignoredSourceMembers = SourceMemberConfigs
                                           .Where(smc => smc.IsIgnored())
                                           .Select(pm => pm.SourceMember.Name).ToList();

                properties = SourceTypeDetails.PublicReadAccessors
                             .Select(p => p.Name)
                             .Except(autoMappedProperties)
                             .Except(redirectedSourceMembers)
                             .Except(ignoredSourceMembers);
            }

            return(properties.Where(memberName => !Profile.GlobalIgnores.Any(memberName.StartsWith)).ToArray());

            string GetPropertyName(PropertyMap pm) => ConfiguredMemberList == MemberList.Destination
                ? pm.DestinationName
                : pm.SourceMember != null
                    ? pm.SourceMember.Name
                    : pm.DestinationName;

            string[] GetPropertyNames(IEnumerable <PropertyMap> propertyMaps) => propertyMaps.Where(pm => pm.IsMapped).Select(GetPropertyName).ToArray();
        }
            public ProductMap(string[] allColumns, webModel.CsvImportMappingItem[]  mappingConfiguration)
            {
                var attributePropertyNames = allColumns.Except(mappingConfiguration.Select(x => x.CsvColumnName));

                foreach (var mappingConfigurationItem in mappingConfiguration)
                {
                    var propertyInfo = typeof(coreModel.CatalogProduct).GetProperty(mappingConfigurationItem.EntityColumnName);
                    var newMap       = new CsvPropertyMap(propertyInfo);
                    newMap.Name(mappingConfigurationItem.CsvColumnName);
                    PropertyMaps.Add(newMap);
                }
                var categoryMappingItem        = mappingConfiguration.First(x => x.EntityColumnName == "Category");
                var editorialReviewMappingItem = mappingConfiguration.First(x => x.EntityColumnName == "Reviews");

                Map(x => x.Category).ConvertUsing(x => new coreModel.Category {
                    Path = x.GetField <string>(categoryMappingItem.CsvColumnName)
                });
                Map(x => x.Reviews).ConvertUsing(x => new coreModel.EditorialReview[] { new coreModel.EditorialReview {
                                                                                            Content = x.GetField <string>(editorialReviewMappingItem.CsvColumnName)
                                                                                        } });
                Map(x => x.PropertyValues).ConvertUsing(x => attributePropertyNames.Select(column => new coreModel.PropertyValue {
                    PropertyName = column, Value = x.GetField <string>(column)
                }).ToList());
            }
Exemple #30
0
 public PropertyMap[] GetPropertyMaps()
 {
     return(_orderedPropertyMaps ?? PropertyMaps.Concat(_inheritedMaps).ToArray());
 }