// <summary> // Create a column map for a ref type // </summary> // <param name="typeInfo"> Type information for the ref type </param> // <param name="name"> Name of the column </param> // <returns> Column map for the ref type </returns> private RefColumnMap CreateRefColumnMap(TypeInfo typeInfo, string name) { SimpleColumnMap entitySetIdColumnMap = null; if (typeInfo.HasEntitySetIdProperty) { entitySetIdColumnMap = CreateSimpleColumnMap( md.Helper.GetModelTypeUsage(typeInfo.EntitySetIdProperty), c_EntitySetIdColumnName); } // get the target entity type, var entityType = (md.EntityType)(TypeHelpers.GetEdmType <md.RefType>(typeInfo.Type).ElementType); // Iterate through the list of "key" properties var keyColList = new SimpleColumnMap[entityType.KeyMembers.Count]; for (var i = 0; i < keyColList.Length; ++i) { var property = entityType.KeyMembers[i]; keyColList[i] = CreateSimpleColumnMap(md.Helper.GetModelTypeUsage(property), property.Name); } // Create the entity identity var identity = CreateEntityIdentity(entityType, entitySetIdColumnMap, keyColList); var result = new RefColumnMap(typeInfo.Type, name, identity); return(result); }
private SimplePolymorphicColumnMap CreatePolymorphicColumnMap( TypeInfo typeInfo, string name) { Dictionary <object, TypedColumnMap> dictionary = new Dictionary <object, TypedColumnMap>(typeInfo.RootType.DiscriminatorMap == null ? (IEqualityComparer <object>)null : (IEqualityComparer <object>)TrailingSpaceComparer.Instance); List <TypedColumnMap> allMaps = new List <TypedColumnMap>(); TypeInfo rootType = (TypeInfo)typeInfo.RootType; SimpleColumnMap typeIdColumnMap = this.CreateTypeIdColumnMap(rootType.TypeIdProperty); if (TypeSemantics.IsComplexType(typeInfo.Type)) { this.CreateComplexTypeColumnMap(rootType, name, (ComplexTypeColumnMap)null, dictionary, allMaps); } else { this.CreateEntityColumnMap(rootType, name, (EntityColumnMap)null, dictionary, allMaps, true); } TypedColumnMap typedColumnMap1 = (TypedColumnMap)null; foreach (TypedColumnMap typedColumnMap2 in allMaps) { if (TypeSemantics.IsStructurallyEqual(typedColumnMap2.Type, typeInfo.Type)) { typedColumnMap1 = typedColumnMap2; break; } } System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(null != typedColumnMap1, "Didn't find requested type in polymorphic type hierarchy?"); return(new SimplePolymorphicColumnMap(typeInfo.Type, name, typedColumnMap1.Properties, typeIdColumnMap, dictionary)); }
// <summary> // Create a column map for a complextype column // </summary> // <param name="typeInfo"> Type information for the type </param> // <param name="name"> column name </param> // <param name="superTypeColumnMap"> Supertype info if any </param> // <param name="discriminatorMap"> Dictionary of typeidvalue->column map </param> // <param name="allMaps"> List of all maps </param> private ComplexTypeColumnMap CreateComplexTypeColumnMap( TypeInfo typeInfo, string name, ComplexTypeColumnMap superTypeColumnMap, Dictionary <object, TypedColumnMap> discriminatorMap, List <TypedColumnMap> allMaps) { var propertyColumnMapList = new List <ColumnMap>(); IEnumerable myProperties = null; SimpleColumnMap nullSentinelColumnMap = null; if (typeInfo.HasNullSentinelProperty) { nullSentinelColumnMap = CreateSimpleColumnMap( md.Helper.GetModelTypeUsage(typeInfo.NullSentinelProperty), c_NullSentinelColumnName); } // Copy over information from my supertype if it already exists if (superTypeColumnMap != null) { foreach (var c in superTypeColumnMap.Properties) { propertyColumnMapList.Add(c); } myProperties = TypeHelpers.GetDeclaredStructuralMembers(typeInfo.Type); } else { // need to get all members otherwise myProperties = TypeHelpers.GetAllStructuralMembers(typeInfo.Type); } // Now add on all of my "specific" properties foreach (md.EdmMember property in myProperties) { var propertyColumnMap = CreateColumnMap(md.Helper.GetModelTypeUsage(property), property.Name); propertyColumnMapList.Add(propertyColumnMap); } // Create a map for myself var columnMap = new ComplexTypeColumnMap(typeInfo.Type, name, propertyColumnMapList.ToArray(), nullSentinelColumnMap); // if a dictionary is supplied, add myself to the dictionary if (discriminatorMap != null) { discriminatorMap[typeInfo.TypeId] = columnMap; } if (allMaps != null) { allMaps.Add(columnMap); } // Finally walk through my subtypes - use the same column name foreach (var subTypeInfo in typeInfo.ImmediateSubTypes) { CreateComplexTypeColumnMap(subTypeInfo, name, columnMap, discriminatorMap, allMaps); } return(columnMap); }
/// <summary> /// Creates a column map for a polymorphic type. This method first /// creates column maps for each type that is a subtype of the input type, /// and then creates a dictionary of typeid value -> column /// Finally, a PolymorphicColumnMap is created with these pieces of information /// </summary> /// <param name="typeInfo">Info about the type</param> /// <param name="name">column name</param> /// <returns></returns> private SimplePolymorphicColumnMap CreatePolymorphicColumnMap(TypeInfo typeInfo, string name) { // if the typeInfo has a DiscriminatorMap, use TrailingSpaceComparer to ensure that lookups // against discriminator values that SQL Server has right-padded (e.g. nchar and char) are properly // interpreted Dictionary <object, TypedColumnMap> discriminatorMap = new Dictionary <object, TypedColumnMap>( typeInfo.RootType.DiscriminatorMap == null ? null : TrailingSpaceComparer.Instance); // abstract types may not have discriminator values, but may nonetheless be interesting List <TypedColumnMap> allMaps = new List <TypedColumnMap>(); // SQLBUDT #433011 -- Polymorphic types must construct column maps // that map to the entire type hierarchy, so we // need to use the RootType, not the current type. TypeInfo rootTypeInfo = typeInfo.RootType; // Get the type discriminant column first SimpleColumnMap typeIdColumnMap = CreateTypeIdColumnMap(rootTypeInfo.TypeIdProperty); // Prepare a place for the constructors to put the columns on the base // type, as they identify them. TypedColumnMap rootTypeColumnMap = null; // process complex/entity types appropriately // use the same name for the column if (md.TypeSemantics.IsComplexType(typeInfo.Type)) { rootTypeColumnMap = CreateComplexTypeColumnMap(rootTypeInfo, name, null, discriminatorMap, allMaps); } else { rootTypeColumnMap = CreateEntityColumnMap(rootTypeInfo, name, null, discriminatorMap, allMaps, true); } // Naturally, nothing is simple; we need to walk the rootTypeColumnMap hierarchy // and find the column map for the type that we are supposed to have as the base // type of this hierarchy. TypedColumnMap baseTypeColumnMap = null; foreach (TypedColumnMap value in allMaps) { if (md.TypeSemantics.IsStructurallyEqual(value.Type, typeInfo.Type)) { baseTypeColumnMap = value; break; } } PlanCompiler.Assert(null != baseTypeColumnMap, "Didn't find requested type in polymorphic type hierarchy?"); // Create a polymorphic column map SimplePolymorphicColumnMap result = new SimplePolymorphicColumnMap(typeInfo.Type, name, baseTypeColumnMap.Properties, typeIdColumnMap, discriminatorMap); return(result); }
private EntityIdentity CreateEntityIdentity( EntityType entityType, SimpleColumnMap entitySetIdColumnMap, SimpleColumnMap[] keyColumnMaps) { if (entitySetIdColumnMap != null) { return((EntityIdentity) new DiscriminatedEntityIdentity(entitySetIdColumnMap, this.m_typeInfo.EntitySetIdToEntitySetMap, keyColumnMaps)); } EntitySet entitySet = this.m_typeInfo.GetEntitySet((EntityTypeBase)entityType); System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(entitySet != null, "Expected non-null entitySet when no entity set ID is required. Entity type = " + (object)entityType); return((EntityIdentity) new SimpleEntityIdentity(entitySet, keyColumnMaps)); }
private ComplexTypeColumnMap CreateComplexTypeColumnMap( TypeInfo typeInfo, string name, ComplexTypeColumnMap superTypeColumnMap, Dictionary <object, TypedColumnMap> discriminatorMap, List <TypedColumnMap> allMaps) { List <ColumnMap> columnMapList = new List <ColumnMap>(); SimpleColumnMap nullSentinel = (SimpleColumnMap)null; if (typeInfo.HasNullSentinelProperty) { nullSentinel = this.CreateSimpleColumnMap(Helper.GetModelTypeUsage((EdmMember)typeInfo.NullSentinelProperty), "__NullSentinel"); } IEnumerable structuralMembers; if (superTypeColumnMap != null) { foreach (ColumnMap property in superTypeColumnMap.Properties) { columnMapList.Add(property); } structuralMembers = TypeHelpers.GetDeclaredStructuralMembers(typeInfo.Type); } else { structuralMembers = (IEnumerable)TypeHelpers.GetAllStructuralMembers(typeInfo.Type); } foreach (EdmMember member in structuralMembers) { ColumnMap columnMap = this.CreateColumnMap(Helper.GetModelTypeUsage(member), member.Name); columnMapList.Add(columnMap); } ComplexTypeColumnMap superTypeColumnMap1 = new ComplexTypeColumnMap(typeInfo.Type, name, columnMapList.ToArray(), nullSentinel); if (discriminatorMap != null) { discriminatorMap[typeInfo.TypeId] = (TypedColumnMap)superTypeColumnMap1; } allMaps?.Add((TypedColumnMap)superTypeColumnMap1); foreach (TypeInfo immediateSubType in typeInfo.ImmediateSubTypes) { this.CreateComplexTypeColumnMap(immediateSubType, name, superTypeColumnMap1, discriminatorMap, allMaps); } return(superTypeColumnMap1); }
/// <summary> /// RecordColumnMap /// </summary> /// <param name="columnMap"></param> /// <param name="translationDelegate"></param> /// <returns></returns> internal override ColumnMap Visit(RecordColumnMap columnMap, ColumnMapTranslatorTranslationDelegate translationDelegate) { SimpleColumnMap newNullSentinel = columnMap.NullSentinel; if (null != newNullSentinel) { newNullSentinel = (SimpleColumnMap)translationDelegate(newNullSentinel); } VisitList(columnMap.Properties, translationDelegate); if (columnMap.NullSentinel != newNullSentinel) { columnMap = new RecordColumnMap(columnMap.Type, columnMap.Name, columnMap.Properties, newNullSentinel); } return(translationDelegate(columnMap)); }
internal override ColumnMap Visit( ComplexTypeColumnMap columnMap, ColumnMapTranslatorTranslationDelegate translationDelegate) { SimpleColumnMap nullSentinel = columnMap.NullSentinel; if (nullSentinel != null) { nullSentinel = (SimpleColumnMap)translationDelegate((ColumnMap)nullSentinel); } this.VisitList <ColumnMap>(columnMap.Properties, translationDelegate); if (columnMap.NullSentinel != nullSentinel) { columnMap = new ComplexTypeColumnMap(columnMap.Type, columnMap.Name, columnMap.Properties, nullSentinel); } return(translationDelegate((ColumnMap)columnMap)); }
private RecordColumnMap CreateRecordColumnMap(TypeInfo typeInfo, string name) { System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(typeInfo.Type.EdmType is RowType, "not RowType"); SimpleColumnMap nullSentinel = (SimpleColumnMap)null; if (typeInfo.HasNullSentinelProperty) { nullSentinel = this.CreateSimpleColumnMap(Helper.GetModelTypeUsage((EdmMember)typeInfo.NullSentinelProperty), "__NullSentinel"); } ReadOnlyMetadataCollection <EdmProperty> properties1 = TypeHelpers.GetProperties(typeInfo.Type); ColumnMap[] properties2 = new ColumnMap[properties1.Count]; for (int index = 0; index < properties2.Length; ++index) { EdmMember member = (EdmMember)properties1[index]; properties2[index] = this.CreateColumnMap(Helper.GetModelTypeUsage(member), member.Name); } return(new RecordColumnMap(typeInfo.Type, name, properties2, nullSentinel)); }
private RefColumnMap CreateRefColumnMap(TypeInfo typeInfo, string name) { SimpleColumnMap entitySetIdColumnMap = (SimpleColumnMap)null; if (typeInfo.HasEntitySetIdProperty) { entitySetIdColumnMap = this.CreateSimpleColumnMap(Helper.GetModelTypeUsage((EdmMember)typeInfo.EntitySetIdProperty), "__EntitySetId"); } EntityType elementType = (EntityType)TypeHelpers.GetEdmType <RefType>(typeInfo.Type).ElementType; SimpleColumnMap[] keyColumnMaps = new SimpleColumnMap[elementType.KeyMembers.Count]; for (int index = 0; index < keyColumnMaps.Length; ++index) { EdmMember keyMember = elementType.KeyMembers[index]; keyColumnMaps[index] = this.CreateSimpleColumnMap(Helper.GetModelTypeUsage(keyMember), keyMember.Name); } EntityIdentity entityIdentity = this.CreateEntityIdentity(elementType, entitySetIdColumnMap, keyColumnMaps); return(new RefColumnMap(typeInfo.Type, name, entityIdentity)); }
/// <summary> /// Build out an EntityIdentity structure - for use by EntityColumnMap and RefColumnMap /// </summary> /// <param name="entityType">the entity type in question</param> /// <param name="entitySetIdColumnMap">column map for the entitysetid column</param> /// <param name="keyColumnMaps">column maps for the keys</param> /// <returns></returns> private EntityIdentity CreateEntityIdentity(md.EntityType entityType, SimpleColumnMap entitySetIdColumnMap, SimpleColumnMap[] keyColumnMaps) { // // If we have an entitysetid (and therefore, a column map for the entitysetid), // then use a discriminated entity identity; otherwise, we use a simpleentityidentity // instead // if (entitySetIdColumnMap != null) { return(new DiscriminatedEntityIdentity(entitySetIdColumnMap, m_typeInfo.EntitySetIdToEntitySetMap, keyColumnMaps)); } else { md.EntitySet entitySet = m_typeInfo.GetEntitySet(entityType); PlanCompiler.Assert(entitySet != null, "Expected non-null entityset when no entitysetid is required. Entity type = " + entityType); return(new SimpleEntityIdentity(entitySet, keyColumnMaps)); } }
/// <summary> /// Create a column map for a record type. Simply iterates through the /// list of fields, and produces a column map for each field /// </summary> /// <param name="typeInfo">Type information for the record type</param> /// <param name="name">column name</param> /// <returns></returns> private RecordColumnMap CreateRecordColumnMap(TypeInfo typeInfo, string name) { PlanCompiler.Assert(typeInfo.Type.EdmType is md.RowType, "not RowType"); SimpleColumnMap nullSentinelColumnMap = null; if (typeInfo.HasNullSentinelProperty) { nullSentinelColumnMap = CreateSimpleColumnMap(md.Helper.GetModelTypeUsage(typeInfo.NullSentinelProperty), c_NullSentinelColumnName); } md.ReadOnlyMetadataCollection <md.EdmProperty> properties = TypeHelpers.GetProperties(typeInfo.Type); ColumnMap[] propertyColumnMapList = new ColumnMap[properties.Count]; for (int i = 0; i < propertyColumnMapList.Length; ++i) { md.EdmMember property = properties[i]; propertyColumnMapList[i] = CreateColumnMap(md.Helper.GetModelTypeUsage(property), property.Name); } RecordColumnMap result = new RecordColumnMap(typeInfo.Type, name, propertyColumnMapList, nullSentinelColumnMap); return(result); }
private EntityColumnMap CreateEntityColumnMap( TypeInfo typeInfo, string name, EntityColumnMap superTypeColumnMap, Dictionary <object, TypedColumnMap> discriminatorMap, List <TypedColumnMap> allMaps, bool handleRelProperties) { EntityColumnMap columnMap = null; var propertyColumnMapList = new List <ColumnMap>(); // Copy over information from my supertype if it already exists if (superTypeColumnMap != null) { // get supertype properties foreach (var c in superTypeColumnMap.Properties) { propertyColumnMapList.Add(c); } // Now add on all of my "specific" properties foreach (md.EdmMember property in TypeHelpers.GetDeclaredStructuralMembers(typeInfo.Type)) { var propertyColumnMap = CreateColumnMap(md.Helper.GetModelTypeUsage(property), property.Name); propertyColumnMapList.Add(propertyColumnMap); } // create the entity column map w/ information from my supertype columnMap = new EntityColumnMap(typeInfo.Type, name, propertyColumnMapList.ToArray(), superTypeColumnMap.EntityIdentity); } else { SimpleColumnMap entitySetIdColumnMap = null; if (typeInfo.HasEntitySetIdProperty) { entitySetIdColumnMap = CreateEntitySetIdColumnMap(typeInfo.EntitySetIdProperty); } // build up a list of key columns var keyColumnMapList = new List <SimpleColumnMap>(); // Create a dictionary to look up the key properties var keyPropertyMap = new Dictionary <md.EdmProperty, ColumnMap>(); foreach (md.EdmMember property in TypeHelpers.GetDeclaredStructuralMembers(typeInfo.Type)) { var propertyColumnMap = CreateColumnMap(md.Helper.GetModelTypeUsage(property), property.Name); propertyColumnMapList.Add(propertyColumnMap); // add property to keymap, if this property is part of the key if (md.TypeSemantics.IsPartOfKey(property)) { var edmProperty = property as md.EdmProperty; PlanCompiler.Assert(edmProperty != null, "EntityType key member is not property?"); keyPropertyMap[edmProperty] = propertyColumnMap; } } // Build up the key list if required foreach (var keyProperty in TypeHelpers.GetEdmType <md.EntityType>(typeInfo.Type).KeyMembers) { var edmKeyProperty = keyProperty as md.EdmProperty; PlanCompiler.Assert(edmKeyProperty != null, "EntityType key member is not property?"); var keyColumnMap = keyPropertyMap[edmKeyProperty] as SimpleColumnMap; PlanCompiler.Assert(keyColumnMap != null, "keyColumnMap is null"); keyColumnMapList.Add(keyColumnMap); } // // Create the entity identity. // var identity = CreateEntityIdentity((md.EntityType)typeInfo.Type.EdmType, entitySetIdColumnMap, keyColumnMapList.ToArray()); // finally create the entity column map columnMap = new EntityColumnMap(typeInfo.Type, name, propertyColumnMapList.ToArray(), identity); } // if a dictionary is supplied, add myself to the dictionary (abstract types need not be added) if (discriminatorMap != null) { // where DiscriminatedNewInstanceOp is used, there will not be an explicit type id for an abstract type // or types that do not appear in the QueryView // (the mapping will not include such information) if (null != typeInfo.TypeId) { discriminatorMap[typeInfo.TypeId] = columnMap; } } if (allMaps != null) { allMaps.Add(columnMap); } // Finally walk through my subtypes foreach (var subTypeInfo in typeInfo.ImmediateSubTypes) { CreateEntityColumnMap(subTypeInfo, name, columnMap, discriminatorMap, allMaps, false); } // // Build up the list of rel property column maps // if (handleRelProperties) { BuildRelPropertyColumnMaps(typeInfo, true); } return(columnMap); }
private EntityColumnMap CreateEntityColumnMap( TypeInfo typeInfo, string name, EntityColumnMap superTypeColumnMap, Dictionary <object, TypedColumnMap> discriminatorMap, List <TypedColumnMap> allMaps, bool handleRelProperties) { List <ColumnMap> columnMapList = new List <ColumnMap>(); EntityColumnMap superTypeColumnMap1; if (superTypeColumnMap != null) { foreach (ColumnMap property in superTypeColumnMap.Properties) { columnMapList.Add(property); } foreach (EdmMember structuralMember in TypeHelpers.GetDeclaredStructuralMembers(typeInfo.Type)) { ColumnMap columnMap = this.CreateColumnMap(Helper.GetModelTypeUsage(structuralMember), structuralMember.Name); columnMapList.Add(columnMap); } superTypeColumnMap1 = new EntityColumnMap(typeInfo.Type, name, columnMapList.ToArray(), superTypeColumnMap.EntityIdentity); } else { SimpleColumnMap entitySetIdColumnMap = (SimpleColumnMap)null; if (typeInfo.HasEntitySetIdProperty) { entitySetIdColumnMap = this.CreateEntitySetIdColumnMap(typeInfo.EntitySetIdProperty); } List <SimpleColumnMap> simpleColumnMapList = new List <SimpleColumnMap>(); Dictionary <EdmProperty, ColumnMap> dictionary = new Dictionary <EdmProperty, ColumnMap>(); foreach (EdmMember structuralMember in TypeHelpers.GetDeclaredStructuralMembers(typeInfo.Type)) { ColumnMap columnMap = this.CreateColumnMap(Helper.GetModelTypeUsage(structuralMember), structuralMember.Name); columnMapList.Add(columnMap); if (TypeSemantics.IsPartOfKey(structuralMember)) { EdmProperty index = structuralMember as EdmProperty; System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(index != null, "EntityType key member is not property?"); dictionary[index] = columnMap; } } foreach (EdmMember keyMember in TypeHelpers.GetEdmType <EntityType>(typeInfo.Type).KeyMembers) { EdmProperty index = keyMember as EdmProperty; System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(index != null, "EntityType key member is not property?"); SimpleColumnMap simpleColumnMap = dictionary[index] as SimpleColumnMap; System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(simpleColumnMap != null, "keyColumnMap is null"); simpleColumnMapList.Add(simpleColumnMap); } EntityIdentity entityIdentity = this.CreateEntityIdentity((EntityType)typeInfo.Type.EdmType, entitySetIdColumnMap, simpleColumnMapList.ToArray()); superTypeColumnMap1 = new EntityColumnMap(typeInfo.Type, name, columnMapList.ToArray(), entityIdentity); } if (discriminatorMap != null && typeInfo.TypeId != null) { discriminatorMap[typeInfo.TypeId] = (TypedColumnMap)superTypeColumnMap1; } allMaps?.Add((TypedColumnMap)superTypeColumnMap1); foreach (TypeInfo immediateSubType in typeInfo.ImmediateSubTypes) { this.CreateEntityColumnMap(immediateSubType, name, superTypeColumnMap1, discriminatorMap, allMaps, false); } if (handleRelProperties) { this.BuildRelPropertyColumnMaps(typeInfo, true); } return(superTypeColumnMap1); }