/// <summary> /// Tries to lookup custom discriminator map for the given type (applies to EntitySets with /// TPH discrimination pattern) /// </summary> private bool TryGetDiscriminatorMap(md.EdmType type, out ExplicitDiscriminatorMap discriminatorMap) { discriminatorMap = null; // check that there are actually discriminator maps available if (null == m_discriminatorMaps) { return(false); } // must be an entity type... if (type.BuiltInTypeKind != md.BuiltInTypeKind.EntityType) { return(false); } // get root entity type (discriminator maps are mapped from the root) md.EntityTypeBase rootEntityType = GetRootType((md.EntityType)type); // find entity set md.EntitySet entitySet; if (!m_entityTypeToEntitySetMap.TryGetValue(rootEntityType, out entitySet)) { return(false); } // free floating entity constructors are stored with a null EntitySet if (entitySet == null) { return(false); } // look for discriminator map return(m_discriminatorMaps.TryGetValue(entitySet, out discriminatorMap)); }
/// <summary> /// Merge the discriminatorMap info we just found with what we've already found. /// In practice, if either the current or the new map is from an OfTypeOnly view, we /// have to avoid the optimizations. /// If we have a new map that is a superset of the current map, then we can just swap /// the new map for the current one. /// If the current map is tha super set of the new one ther's nothing to do. /// (Of course, if neither has changed, then we really don't need to look) /// </summary> internal void Merge(EntityTypeBase neededRootEntityType, bool includesSubtypes, ExplicitDiscriminatorMap discriminatorMap) { // If what we've found doesn't exactly match what we are looking for we have more work to do if (RootEntityType != neededRootEntityType || IncludesSubTypes != includesSubtypes) { if (!IncludesSubTypes || !includesSubtypes) { // If either the original or the new map is from an of-type-only view we can't // merge, we just have to not optimize this case. DiscriminatorMap = null; } if (TypeSemantics.IsSubTypeOf(RootEntityType, neededRootEntityType)) { // we're asking for a super type of existing type, and what we had is a proper // subset of it -we can replace the existing item. RootEntityType = neededRootEntityType; DiscriminatorMap = discriminatorMap; } if (!TypeSemantics.IsSubTypeOf(neededRootEntityType, RootEntityType)) { // If either the original or the new map is from an of-type-only view we can't // merge, we just have to not optimize this case. DiscriminatorMap = null; } } }
/// <summary> /// Handle discriminator maps (determine which can safely be used in the query) /// </summary> private void ProcessDiscriminatorMaps(Dictionary <md.EntitySetBase, DiscriminatorMapInfo> discriminatorMaps) { // Only use custom type discrimination where a type has a single entity set. Where // there are multiple sets, discriminator properties and flattened representations // may be incompatible. Dictionary <md.EntitySetBase, ExplicitDiscriminatorMap> filteredMaps = null; if (null != discriminatorMaps) { filteredMaps = new Dictionary <md.EntitySetBase, ExplicitDiscriminatorMap>(discriminatorMaps.Count, discriminatorMaps.Comparer); foreach (KeyValuePair <md.EntitySetBase, DiscriminatorMapInfo> setMapPair in discriminatorMaps) { md.EntitySetBase set = setMapPair.Key; ExplicitDiscriminatorMap map = setMapPair.Value.DiscriminatorMap; if (null != map) { md.EntityTypeBase rootType = GetRootType(set.ElementType); bool hasOneSet = GetEntitySet(rootType) != null; if (hasOneSet) { filteredMaps.Add(set, map); } } } if (filteredMaps.Count == 0) { // don't bother keeping the dictionary if it's empty filteredMaps = null; } } m_discriminatorMaps = filteredMaps; }
internal static TypeInfo Create( TypeUsage type, TypeInfo superTypeInfo, ExplicitDiscriminatorMap discriminatorMap) { return(superTypeInfo != null ? new TypeInfo(type, superTypeInfo) : (TypeInfo) new RootTypeInfo(type, discriminatorMap)); }
internal DiscriminatorMapInfo( EntityTypeBase rootEntityType, bool includesSubTypes, ExplicitDiscriminatorMap discriminatorMap) { this.RootEntityType = rootEntityType; this.IncludesSubTypes = includesSubTypes; this.DiscriminatorMap = discriminatorMap; }
internal RootTypeInfo(TypeUsage type, ExplicitDiscriminatorMap discriminatorMap) : base(type, (TypeInfo)null) { System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(type.EdmType.BaseType == null, "only root types allowed here"); this.m_propertyMap = new Dictionary <PropertyRef, EdmProperty>(); this.m_propertyRefList = new List <PropertyRef>(); this.m_discriminatorMap = discriminatorMap; this.TypeIdKind = TypeIdKind.Generated; }
internal RootTypeInfo(TypeUsage type, ExplicitDiscriminatorMap discriminatorMap) : base(type, null) { PlanCompiler.Assert(type.EdmType.BaseType == null, "only root types allowed here"); m_propertyMap = new Dictionary <PropertyRef, EdmProperty>(); m_propertyRefList = new List <PropertyRef>(); m_discriminatorMap = discriminatorMap; TypeIdKind = TypeIdKind.Generated; }
private bool TryGetDiscriminatorMap(EdmType type, out ExplicitDiscriminatorMap discriminatorMap) { discriminatorMap = (ExplicitDiscriminatorMap)null; EntitySet entitySet; if (this.m_discriminatorMaps == null || type.BuiltInTypeKind != BuiltInTypeKind.EntityType || (!this.m_entityTypeToEntitySetMap.TryGetValue(StructuredTypeInfo.GetRootType((EntityTypeBase)type), out entitySet) || entitySet == null)) { return(false); } return(this.m_discriminatorMaps.TryGetValue((EntitySetBase)entitySet, out discriminatorMap)); }
private readonly RootTypeInfo m_rootType; // the top-most type in this types type hierarchy #endregion #region Constructors and factory methods // <summary> // Creates type information for a type // </summary> internal static TypeInfo Create(md.TypeUsage type, TypeInfo superTypeInfo, ExplicitDiscriminatorMap discriminatorMap) { TypeInfo result; if (superTypeInfo == null) { result = new RootTypeInfo(type, discriminatorMap); } else { result = new TypeInfo(type, superTypeInfo); } return(result); }
private TypeInfo CreateTypeInfoForStructuredType( TypeUsage type, ExplicitDiscriminatorMap discriminatorMap) { System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(TypeUtils.IsStructuredType(type), "expected structured type. Found " + (object)type); TypeInfo typeInfo1 = this.GetTypeInfo(type); if (typeInfo1 != null) { return(typeInfo1); } TypeInfo superTypeInfo = (TypeInfo)null; if (type.EdmType.BaseType != null) { superTypeInfo = this.CreateTypeInfoForStructuredType(TypeUsage.Create(type.EdmType.BaseType), discriminatorMap); } else { RefType type1; if (TypeHelpers.TryGetEdmType <RefType>(type, out type1)) { EntityType elementType = type1.ElementType as EntityType; if (elementType != null && elementType.BaseType != null) { superTypeInfo = this.CreateTypeInfoForStructuredType(TypeHelpers.CreateReferenceTypeUsage(elementType.BaseType as EntityType), discriminatorMap); } } } foreach (EdmMember structuralMember in TypeHelpers.GetDeclaredStructuralMembers(type)) { this.CreateTypeInfoForType(structuralMember.TypeUsage); } EntityTypeBase type2; if (TypeHelpers.TryGetEdmType <EntityTypeBase>(type, out type2)) { foreach (RelProperty declaredOnlyRelProperty in this.m_relPropertyHelper.GetDeclaredOnlyRelProperties(type2)) { this.CreateTypeInfoForType(declaredOnlyRelProperty.ToEnd.TypeUsage); } } TypeInfo typeInfo2 = TypeInfo.Create(type, superTypeInfo, discriminatorMap); this.m_typeInfoMap.Add(type, typeInfo2); return(typeInfo2); }
internal void Merge( EntityTypeBase neededRootEntityType, bool includesSubtypes, ExplicitDiscriminatorMap discriminatorMap) { if (this.RootEntityType == neededRootEntityType && this.IncludesSubTypes == includesSubtypes) { return; } if (!this.IncludesSubTypes || !includesSubtypes) { this.DiscriminatorMap = (ExplicitDiscriminatorMap)null; } if (TypeSemantics.IsSubTypeOf((EdmType)this.RootEntityType, (EdmType)neededRootEntityType)) { this.RootEntityType = neededRootEntityType; this.DiscriminatorMap = discriminatorMap; } if (TypeSemantics.IsSubTypeOf((EdmType)neededRootEntityType, (EdmType)this.RootEntityType)) { return; } this.DiscriminatorMap = (ExplicitDiscriminatorMap)null; }
private void ProcessDiscriminatorMaps( Dictionary <EntitySetBase, DiscriminatorMapInfo> discriminatorMaps) { Dictionary <EntitySetBase, ExplicitDiscriminatorMap> dictionary = (Dictionary <EntitySetBase, ExplicitDiscriminatorMap>)null; if (discriminatorMaps != null) { dictionary = new Dictionary <EntitySetBase, ExplicitDiscriminatorMap>(discriminatorMaps.Count, discriminatorMaps.Comparer); foreach (KeyValuePair <EntitySetBase, DiscriminatorMapInfo> discriminatorMap1 in discriminatorMaps) { EntitySetBase key = discriminatorMap1.Key; ExplicitDiscriminatorMap discriminatorMap2 = discriminatorMap1.Value.DiscriminatorMap; if (discriminatorMap2 != null && this.GetEntitySet(StructuredTypeInfo.GetRootType(key.ElementType)) != null) { dictionary.Add(key, discriminatorMap2); } } if (dictionary.Count == 0) { dictionary = (Dictionary <EntitySetBase, ExplicitDiscriminatorMap>)null; } } this.m_discriminatorMaps = dictionary; }
private TypeInfo CreateTypeInfoForStructuredType(md.TypeUsage type, ExplicitDiscriminatorMap discriminatorMap) { TypeInfo typeInfo; PlanCompiler.Assert(TypeUtils.IsStructuredType(type), "expected structured type. Found " + type); // Return existing entry, if one is available typeInfo = GetTypeInfo(type); if (typeInfo != null) { return(typeInfo); } // Ensure that my supertype has been added to the map. TypeInfo superTypeInfo = null; md.RefType refType; if (type.EdmType.BaseType != null) { superTypeInfo = CreateTypeInfoForStructuredType(md.TypeUsage.Create(type.EdmType.BaseType), discriminatorMap); } // // Handle Ref types also in a similar fashion // else if (TypeHelpers.TryGetEdmType(type, out refType)) { var entityType = refType.ElementType as md.EntityType; if (entityType != null && entityType.BaseType != null) { var baseRefType = TypeHelpers.CreateReferenceTypeUsage(entityType.BaseType as md.EntityType); superTypeInfo = CreateTypeInfoForStructuredType(baseRefType, discriminatorMap); } } // // Add the types of my properties to the TypeInfo map // foreach (md.EdmMember m in TypeHelpers.GetDeclaredStructuralMembers(type)) { CreateTypeInfoForType(m.TypeUsage); } // // Get the types of the rel properties also // { md.EntityTypeBase entityType; if (TypeHelpers.TryGetEdmType(type, out entityType)) { foreach (var p in m_relPropertyHelper.GetDeclaredOnlyRelProperties(entityType)) { CreateTypeInfoForType(p.ToEnd.TypeUsage); } } } // Now add myself to the map typeInfo = TypeInfo.Create(type, superTypeInfo, discriminatorMap); m_typeInfoMap.Add(type, typeInfo); return(typeInfo); }