private ReferenceContext(string segment, ReferenceContext parent, TableStore store, ClassMapping cMapping) { Store = store; CMapping = cMapping; //init lists Children = new List <ReferenceContext>(); ParentContext = parent; //try to extract TypeOf part of the path var parts = segment.Split('\\'); segment = parts[0]; var typeHint = parts.Length > 1 ? parts[1] : null; Segment = segment; //set up path type hint if it is defined if (!string.IsNullOrWhiteSpace(typeHint)) { PathTypeHint = Store.MetaData.ExpressType(typeHint.ToUpper()); } if (segment == "parent") { PathTypeHint = Store.MetaData.ExpressType(CMapping.ParentClass.ToUpper()); ContextType = ReferenceContextType.Parent; return; } Index = TableStore.GetPropertyIndex(ref segment); PropertyInfo = Store.GetPropertyInfo(segment, parent.SegmentType, Index); MetaProperty = Store.GetProperty(parent.SegmentType, segment); var info = PropertyInfo != null ? PropertyInfo.PropertyType : (MetaProperty != null ? MetaProperty.EnumerableType ?? MetaProperty.PropertyInfo.PropertyType : null); if (info == null) { Store.Log.WriteLine("Type {0} doesn't have a property {1}.", parent.PathTypeHint.ExpressName, segment); return; } PropertyTypeHint = Store.MetaData.ExpressType(MetaProperty != null ? MetaProperty.EnumerableType ?? MetaProperty.PropertyInfo.PropertyType : (PropertyInfo != null ? PropertyInfo.PropertyType : null) ); //set up type of the context var isEnumerable = MetaProperty != null && MetaProperty.EnumerableType != null; if (isEnumerable) { if (MetaProperty.EnumerableType.IsValueType || MetaProperty.EnumerableType == typeof(string) || typeof(IExpressValueType).IsAssignableFrom(MetaProperty.EnumerableType)) { ContextType = ReferenceContextType.ScalarList; } else { ContextType = ReferenceContextType.EntityList; } } else { if (info.IsValueType || info == typeof(string) || typeof(IExpressValueType).IsAssignableFrom(info)) { ContextType = ReferenceContextType.Scalar; } else { ContextType = ReferenceContextType.Entity; } } }
private void Store(ISheet sheet, IPersistEntity entity, ClassMapping mapping, ExpressType expType, EntityContext context) { var multiRow = -1; List <string> multiValues = null; PropertyMapping multiMapping = null; var row = GetRow(sheet); //fix on "Special Case" Assembly Row to Entity mapping if ((context?.RootEntity != null) && (expType?.ExpressNameUpper == "TYPEORCOMPONENT")) //without CobieExpress reference and not using reflection this is as good as it gets to ID Assembly { RowNoToEntityLabelLookup[sheet.SheetName].Add(row.RowNum, context.RootEntity.EntityLabel); } else { RowNoToEntityLabelLookup[sheet.SheetName].Add(row.RowNum, entity.EntityLabel); } foreach (var propertyMapping in mapping.PropertyMappings) { object value = null; foreach (var path in propertyMapping.Paths) { value = GetValue(entity, expType, path, context); if (value != null) { break; } } if (value == null && propertyMapping.Status == DataStatus.Required) { value = propertyMapping.DefaultValue ?? "n/a"; } var isMultiRow = IsMultiRow(value, propertyMapping); if (isMultiRow) { multiRow = row.RowNum; var values = new List <string>(); var enumerable = value as IEnumerable <string>; if (enumerable != null) { values.AddRange(enumerable); } //get only first value and store it var first = values.First(); Store(row, first, propertyMapping); //set the rest for the processing as multiValue values.Remove(first); multiValues = values; multiMapping = propertyMapping; } else { Store(row, value, propertyMapping); } } //adjust width of the columns after the first and the eight row //adjusting fully populated workbook takes ages. This should be almost all right if (row.RowNum == 1 || row.RowNum == 8) { AdjustAllColumns(sheet, mapping); } //it is not a multi row so return if (multiRow <= 0 || multiValues == null || !multiValues.Any()) { return; } //add repeated rows if necessary foreach (var value in multiValues) { var rowNum = GetNextRowNum(sheet); var copy = sheet.CopyRow(multiRow, rowNum); Store(copy, value, multiMapping); RowNoToEntityLabelLookup[sheet.SheetName].Add(rowNum, entity.EntityLabel); } }