protected ExtractInfo CreateExtractInfo(Type targetClassType, int schemeId, int extractLevel) { //Check cache ExtractInfo result; if (_ExtractInfoCache.TryGetExtractInfo(targetClassType, schemeId, out result)) { return(result); } result = new ExtractInfo(targetClassType, schemeId); _ExtractInfoCache.Add(targetClassType, schemeId, result); _MappingProvider.GetExtractInfo(result); //resolving nested types foreach (var item in result.SubTypes) { if (item.RelatedExtractInfo.TargetType == null) { item.RelatedExtractInfo.TargetType = ReflectionHelper.GetReturnType(item.Member); } } foreach (var item in result.ChildTypes) { if (item.RelatedExtractInfo.TargetType == null) { item.RelatedExtractInfo.TargetType = ReflectionHelper.GetListItemType( ReflectionHelper.GetReturnType(item.Member)); if (item.KeyInfo != null) { item.KeyInfo.ChildType = item.RelatedExtractInfo.TargetType; } } if (item.RelatedExtractInfo.TargetType == null) { throw new DataMapperException("Cannot resolve type of items in collection(" + item.Member.Name + "). " + "Try to set it via ItemType property of DataRelationMapAttribute."); } } //distinct same keys foreach (var item1 in result.ChildTypes) { foreach (var item2 in result.ChildTypes) { var key1 = item1.KeyInfo; if (key1 != null && key1.Equals(item2.KeyInfo)) { item2.KeyInfo = key1; } } } DumpExtractInfo(result, extractLevel); //fill child types (recursive) foreach (var item in result.SubTypes) { item.RelatedExtractInfo = CreateExtractInfo( item.RelatedExtractInfo.TargetType, item.RelatedExtractInfo.SchemeId, extractLevel + 1); } foreach (var item in result.ChildTypes) { item.RelatedExtractInfo = CreateExtractInfo( item.RelatedExtractInfo.TargetType, item.RelatedExtractInfo.SchemeId, extractLevel + 1); } //fill foreign keys if (extractLevel == 0) { result.ResolveForeign(); } return(result); }