/// <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; } } }
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 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> /// <param name="type"></param> /// <param name="superTypeInfo"></param> /// <returns></returns> 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; }
/// <summary> /// Create a discriminated named type constructor /// </summary> /// <param name="type">Type metadata that specifies the type of the instance to construct</param> /// <param name="discriminatorMap">Mapping information including discriminator values</param> /// <param name="entitySet">the entityset that this instance belongs to</param> /// <param name="relProperties">list of rel properties that have corresponding values</param> /// <returns>A new DiscriminatedNewInstanceOp with the specified result type and discrimination behavior</returns> internal DiscriminatedNewEntityOp CreateDiscriminatedNewEntityOp(TypeUsage type, ExplicitDiscriminatorMap discriminatorMap, EntitySet entitySet, List<RelProperty> relProperties) { return new DiscriminatedNewEntityOp(type, discriminatorMap, entitySet, relProperties); }
/// <summary> /// Add a new entry to the map. If an entry already exists, then this function /// simply returns the existing entry. Otherwise a new entry is created. If /// the type has a supertype, then we ensure that the supertype also exists in /// the map, and we add our info to the supertype's list of subtypes /// </summary> /// <param name="type">New type to add</param> /// <param name="discriminatorMap">type discriminator map</param> /// <returns>The TypeInfo for this type</returns> 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<md.RefType>(type, out refType)) { md.EntityType entityType = refType.ElementType as md.EntityType; if (entityType != null && entityType.BaseType != null) { md.TypeUsage 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<md.EntityTypeBase>(type, out entityType)) { foreach (RelProperty 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; }
/// <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); }
internal DiscriminatorMapInfo(EntityTypeBase rootEntityType, bool includesSubTypes, ExplicitDiscriminatorMap discriminatorMap) { RootEntityType = rootEntityType; IncludesSubTypes = includesSubTypes; DiscriminatorMap = discriminatorMap; }