private object LoadObjectTree(LayerInfo layer, IDataReader reader, out bool successRead) { var val = (IComparable)reader.GetValue(layer.LayerOffset); var entityObject = layer.CreatingDelegate(reader, layer.LayerOffset); var notfirst = false; foreach (var fillingDelegate in layer.FillingDelegates) { fillingDelegate(reader, entityObject, layer.LayerOffset + (notfirst ? 1 : 2)); notfirst = true; } successRead = true; if (layer.NextLayer != null) { //todo: nav-filling delegates - separate var nextPart = (SubTypePart) layer.NextLayer.TypePart; var property = entityObject.GetType().GetProperty(nextPart.CollectingProperty.Name); if (property.PropertyType.IsCollection()) { var itemType = property.PropertyType.GetCollectionType(); var collection = (IList) Activator.CreateInstance(typeof (List<>).MakeGenericType(itemType)); while (successRead && ((IComparable)reader.GetValue(layer.LayerOffset)).CompareTo(val) == 0) { var propObj = LoadObjectTree(layer.NextLayer, reader, out successRead); collection.Add(propObj); } if (property.PropertyType.IsArray) { var array = Array.CreateInstance(itemType, collection.Count); collection.CopyTo(array, 0); property.SetValue(entityObject, array); } else { property.SetValue(entityObject, collection); } } else { while (successRead && ((IComparable)reader.GetValue(layer.LayerOffset)).CompareTo(val) == 0) { var propObj = LoadObjectTree(layer.NextLayer, reader, out successRead); property.SetValue(entityObject, propObj); } } } else if (layer.Expansions.Count > 0) { var exp = layer.Expansions.First(); var property = entityObject.GetType().GetProperty(exp.CollectingProperty.Name); var itemType = property.PropertyType.GetCollectionType(); var primitive = (PrimitiveListTable)exp.Table; var collection = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(itemType)); if (primitive.MaintainOrder) { var dictionary = new SortedDictionary<long, object>(); var offset = layer.LayerEnds; while (successRead && ((IComparable) reader.GetValue(layer.LayerOffset)).CompareTo(val) == 0) { var k = reader.GetInt64(offset + 2); var v = reader.GetValue(offset + 1); dictionary[k] = v; successRead = reader.Read(); } //todo: optimize foreach (var item in dictionary) { collection.Add(item.Value); } } else { var offset = layer.LayerEnds; while (successRead && ((IComparable)reader.GetValue(layer.LayerOffset)).CompareTo(val) == 0) { var v = reader.GetValue(offset + 1); collection.Add(v); successRead = reader.Read(); } } if (property.PropertyType.IsArray) { var array = Array.CreateInstance(itemType, collection.Count); collection.CopyTo(array, 0); property.SetValue(entityObject, array); } else { property.SetValue(entityObject, collection); } } else { successRead = reader.Read(); } return entityObject; }