/// <summary> /// Creates a column map for the given reader and function mapping. /// </summary> internal static CollectionColumnMap CreateFunctionImportStructuralTypeColumnMap(DbDataReader storeDataReader, FunctionImportMappingNonComposable mapping, int resultSetIndex, EntitySet entitySet, StructuralType baseStructuralType) { FunctionImportStructuralTypeMappingKB resultMapping = mapping.GetResultMapping(resultSetIndex); Debug.Assert(resultMapping != null); if (resultMapping.NormalizedEntityTypeMappings.Count == 0) // no explicit mapping; use default non-polymorphic reader { // if there is no mapping, create default mapping to root entity type or complex type Debug.Assert(!baseStructuralType.Abstract, "mapping loader must verify abstract types have explicit mapping"); return(CreateColumnMapFromReaderAndType(storeDataReader, baseStructuralType, entitySet, resultMapping.ReturnTypeColumnsRenameMapping)); } // the section below deals with the polymorphic entity type mapping for return type EntityType baseEntityType = baseStructuralType as EntityType; Debug.Assert(null != baseEntityType, "We should have entity type here"); // Generate column maps for all discriminators ScalarColumnMap[] discriminatorColumns = CreateDiscriminatorColumnMaps(storeDataReader, mapping, resultSetIndex); // Generate default maps for all mapped entity types var mappedEntityTypes = new HashSet <EntityType>(resultMapping.MappedEntityTypes); mappedEntityTypes.Add(baseEntityType); // make sure the base type is represented Dictionary <EntityType, TypedColumnMap> typeChoices = new Dictionary <EntityType, TypedColumnMap>(mappedEntityTypes.Count); ColumnMap[] baseTypeColumnMaps = null; foreach (EntityType entityType in mappedEntityTypes) { ColumnMap[] propertyColumnMaps = GetColumnMapsForType(storeDataReader, entityType, resultMapping.ReturnTypeColumnsRenameMapping); EntityColumnMap entityColumnMap = CreateEntityTypeElementColumnMap(storeDataReader, entityType, entitySet, propertyColumnMaps, resultMapping.ReturnTypeColumnsRenameMapping); if (!entityType.Abstract) { typeChoices.Add(entityType, entityColumnMap); } if (entityType == baseStructuralType) { baseTypeColumnMaps = propertyColumnMaps; } } // NOTE: We don't have a null sentinel here, because the stored proc won't // return one anyway; we'll just presume the data's always there. MultipleDiscriminatorPolymorphicColumnMap polymorphicMap = new MultipleDiscriminatorPolymorphicColumnMap(TypeUsage.Create(baseStructuralType), baseStructuralType.Name, baseTypeColumnMaps, discriminatorColumns, typeChoices, (object[] discriminatorValues) => mapping.Discriminate(discriminatorValues, resultSetIndex)); CollectionColumnMap collection = new SimpleCollectionColumnMap(baseStructuralType.GetCollectionType().TypeUsage, baseStructuralType.Name, polymorphicMap, null, null); return(collection); }
internal virtual CollectionColumnMap CreateFunctionImportStructuralTypeColumnMap( DbDataReader storeDataReader, FunctionImportMappingNonComposable mapping, int resultSetIndex, EntitySet entitySet, StructuralType baseStructuralType) { FunctionImportStructuralTypeMappingKB resultMapping = mapping.GetResultMapping(resultSetIndex); if (resultMapping.NormalizedEntityTypeMappings.Count == 0) { return(this.CreateColumnMapFromReaderAndType(storeDataReader, (EdmType)baseStructuralType, entitySet, resultMapping.ReturnTypeColumnsRenameMapping)); } EntityType entityType = baseStructuralType as EntityType; ScalarColumnMap[] discriminatorColumnMaps = ColumnMapFactory.CreateDiscriminatorColumnMaps(storeDataReader, mapping, resultSetIndex); HashSet <EntityType> entityTypeSet = new HashSet <EntityType>((IEnumerable <EntityType>)resultMapping.MappedEntityTypes); entityTypeSet.Add(entityType); Dictionary <EntityType, TypedColumnMap> typeChoices = new Dictionary <EntityType, TypedColumnMap>(entityTypeSet.Count); ColumnMap[] baseTypeColumns = (ColumnMap[])null; foreach (EntityType key in entityTypeSet) { ColumnMap[] columnMapsForType = ColumnMapFactory.GetColumnMapsForType(storeDataReader, (EdmType)key, resultMapping.ReturnTypeColumnsRenameMapping); EntityColumnMap elementColumnMap = ColumnMapFactory.CreateEntityTypeElementColumnMap(storeDataReader, (EdmType)key, entitySet, columnMapsForType, resultMapping.ReturnTypeColumnsRenameMapping); if (!key.Abstract) { typeChoices.Add(key, (TypedColumnMap)elementColumnMap); } if (key == baseStructuralType) { baseTypeColumns = columnMapsForType; } } MultipleDiscriminatorPolymorphicColumnMap polymorphicColumnMap = new MultipleDiscriminatorPolymorphicColumnMap(TypeUsage.Create((EdmType)baseStructuralType), baseStructuralType.Name, baseTypeColumns, (SimpleColumnMap[])discriminatorColumnMaps, typeChoices, (Func <object[], EntityType>)(discriminatorValues => mapping.Discriminate(discriminatorValues, resultSetIndex))); return((CollectionColumnMap) new SimpleCollectionColumnMap(baseStructuralType.GetCollectionType().TypeUsage, baseStructuralType.Name, (ColumnMap)polymorphicColumnMap, (SimpleColumnMap[])null, (SimpleColumnMap[])null)); }