public static async Task <EntityViewModel> CreateRecursive(Document doc, int depth = 3, bool autoSelect = true, bool canSelectCollections = true, List <string> existingProperties = null, bool canReuseBaseMapper = false) { var instance = new EntityViewModel(); instance.Properties = new ObservableCollection <PropertyViewModel>(); instance._originalMetadata = await EntityParser.FromDocument(doc, includeInherited : true); instance.EntityName = instance._originalMetadata.Name; foreach (var p in instance._originalMetadata.Properties) { var propViewModel = new PropertyViewModel(instance); propViewModel.Name = p.Name; propViewModel.IsInherited = p.IsInherited; propViewModel.IsVisible = true; propViewModel.Type = p.Type; propViewModel.CanSelect = true; if (p.IsCollection && !canSelectCollections) { propViewModel.CanSelect = false; } propViewModel.IsSelected = autoSelect && p.IsSimpleProperty; if (existingProperties != null) { propViewModel.IsSelected = propViewModel.CanSelect && existingProperties.Any(x => x == p.Name); } if (p.IsRelation && !p.IsCollection && depth > 0) { var relatedDoc = await doc.GetRelatedEntityDocument(p.RelatedEntityName); if (relatedDoc != null) { var relatedProperties = existingProperties == null ? null : existingProperties.Where(x => x.StartsWith(p.Name)) .Where(x => !instance._originalMetadata.Properties.Any(o => o.Name == x)) .Select(x => x.Substring(p.Name.Length)) .ToList(); propViewModel.RelatedEntity = await CreateRecursive(relatedDoc, depth : depth - 1, autoSelect : false, canSelectCollections : false, existingProperties : relatedProperties); } else { p.IsRelation = false; p.IsSimpleProperty = true; } } instance.Properties.Add(propViewModel); } if (canReuseBaseMapper && !string.IsNullOrWhiteSpace(instance._originalMetadata.BaseClassDtoName)) { instance.CanReuseBaseMapper = true; instance.BaseEntityDtoName = instance._originalMetadata.BaseClassDtoName; if (existingProperties == null) { instance.ReuseBaseEntityMapper = true; } } return(instance); }