Пример #1
0
        /// <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;
         }
     }
 }
Пример #3
0
        /// <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;
        }
Пример #4
0
 internal static TypeInfo Create(
     TypeUsage type,
     TypeInfo superTypeInfo,
     ExplicitDiscriminatorMap discriminatorMap)
 {
     return(superTypeInfo != null ? new TypeInfo(type, superTypeInfo) : (TypeInfo) new RootTypeInfo(type, discriminatorMap));
 }
Пример #5
0
 internal DiscriminatorMapInfo(
     EntityTypeBase rootEntityType,
     bool includesSubTypes,
     ExplicitDiscriminatorMap discriminatorMap)
 {
     this.RootEntityType   = rootEntityType;
     this.IncludesSubTypes = includesSubTypes;
     this.DiscriminatorMap = discriminatorMap;
 }
Пример #6
0
 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;
 }
Пример #7
0
        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;
        }
Пример #8
0
        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));
        }
Пример #9
0
        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);
        }
Пример #10
0
        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);
        }
Пример #11
0
 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;
 }
Пример #12
0
        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);
        }