/// <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 DiscriminatedNewEntityOp( TypeUsage type, ExplicitDiscriminatorMap discriminatorMap, EntitySet entitySet, List <RelProperty> relProperties) : base(OpType.DiscriminatedNewEntity, type, true, entitySet, relProperties) { DebugCheck.NotNull(discriminatorMap); m_discriminatorMap = discriminatorMap; }
internal virtual DiscriminatedNewEntityOp CreateDiscriminatedNewEntityOp( TypeUsage type, ExplicitDiscriminatorMap discriminatorMap, EntitySet entitySet, List <RelProperty> relProperties) { return(new DiscriminatedNewEntityOp(type, discriminatorMap, entitySet, relProperties)); }
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; }
internal DiscriminatorMapInfo(EntityTypeBase rootEntityType, bool includesSubTypes, ExplicitDiscriminatorMap discriminatorMap) { RootEntityType = rootEntityType; IncludesSubTypes = includesSubTypes; DiscriminatorMap = discriminatorMap; }
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; }
// <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) var 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> // 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 virtual DiscriminatedNewEntityOp CreateDiscriminatedNewEntityOp( TypeUsage type, ExplicitDiscriminatorMap discriminatorMap, EntitySet entitySet, List<RelProperty> relProperties) { return new DiscriminatedNewEntityOp(type, discriminatorMap, entitySet, relProperties); }