Пример #1
0
 private void ExplodeRootStructuredType(RootTypeInfo rootType)
 {
     if (rootType.FlattenedType != null)
     {
         return;
     }
     if (StructuredTypeInfo.NeedsTypeIdProperty((TypeInfo)rootType))
     {
         rootType.AddPropertyRef((PropertyRef)TypeIdPropertyRef.Instance);
         if (rootType.DiscriminatorMap != null)
         {
             rootType.TypeIdKind = TypeIdKind.UserSpecified;
             rootType.TypeIdType = Helper.GetModelTypeUsage(rootType.DiscriminatorMap.DiscriminatorProperty);
         }
         else
         {
             rootType.TypeIdKind = TypeIdKind.Generated;
             rootType.TypeIdType = this.m_stringType;
         }
     }
     if (this.NeedsEntitySetIdProperty((TypeInfo)rootType))
     {
         rootType.AddPropertyRef((PropertyRef)EntitySetIdPropertyRef.Instance);
     }
     if (this.NeedsNullSentinelProperty((TypeInfo)rootType))
     {
         rootType.AddPropertyRef((PropertyRef)NullSentinelPropertyRef.Instance);
     }
     this.ExplodeRootStructuredTypeHelper((TypeInfo)rootType);
     if (TypeSemantics.IsEntityType(rootType.Type))
     {
         this.AddRelProperties((TypeInfo)rootType);
     }
     this.CreateFlattenedRecordType(rootType);
 }
        // <summary>
        // "Explode" a root type. (ie) add each member of the type to a flat list of
        // members for the supertype.
        // Type explosion works in a DFS style model. We first walk through the
        // list of properties for the current type, and "flatten" out the properties
        // that are themselves "structured". We then target each subtype (recursively)
        // and perform the same kind of processing.
        // Consider a very simple case:
        // Q = (z1 int, z2 date)
        // Q2: Q = (z3 string)  -- Q2 is a subtype of Q
        // T = (a int, b Q, c date)
        // S: T = (d int)  -- read as S is a subtype of T
        // The result of flattening T (and S) will be
        // (a int, b.z1 int, b.z2 date, b.z3 string, c date, d int)
        // </summary>
        // <param name="rootType"> the root type to explode </param>
        private void ExplodeRootStructuredType(RootTypeInfo rootType)
        {
            // Already done??
            if (rootType.FlattenedType != null)
            {
                return;
            }

            //
            // Special handling for root types. Add any special
            // properties that are needed - TypeId, EntitySetId, etc
            //
            if (NeedsTypeIdProperty(rootType))
            {
                rootType.AddPropertyRef(TypeIdPropertyRef.Instance);
                // check for discriminator map; if one exists, use custom discriminator member; otherwise, use default
                if (null != rootType.DiscriminatorMap)
                {
                    rootType.TypeIdKind = TypeIdKind.UserSpecified;
                    rootType.TypeIdType = md.Helper.GetModelTypeUsage(rootType.DiscriminatorMap.DiscriminatorProperty);
                }
                else
                {
                    rootType.TypeIdKind = TypeIdKind.Generated;
                    rootType.TypeIdType = m_stringType;
                }
            }
            if (NeedsEntitySetIdProperty(rootType))
            {
                rootType.AddPropertyRef(EntitySetIdPropertyRef.Instance);
            }
            if (NeedsNullSentinelProperty(rootType))
            {
                rootType.AddPropertyRef(NullSentinelPropertyRef.Instance);
            }

            //
            // Then add members from each type in the hierarchy (including
            // the root type)
            //
            ExplodeRootStructuredTypeHelper(rootType);

            //
            // For entity types, add all the rel-properties now. Note that rel-properties
            // are added after the regular properties of all subtypes
            //
            if (md.TypeSemantics.IsEntityType(rootType.Type))
            {
                AddRelProperties(rootType);
            }

            //
            // We've now gotten all the relevant properties
            // Now let's create a new record type
            //
            CreateFlattenedRecordType(rootType);
        }
        private md.TypeUsage GetPropertyType(RootTypeInfo typeInfo, PropertyRef p)
        {
            md.TypeUsage result = null;

            PropertyRef innerProperty = null;

            // Get the "leaf" property first
            while (p is NestedPropertyRef)
            {
                var npr = (NestedPropertyRef)p;
                p             = npr.OuterProperty;
                innerProperty = npr.InnerProperty;
            }

            if (p is TypeIdPropertyRef)
            {
                //
                // Get to the innermost type that specifies this typeid (the entity type),
                // get the datatype for the typeid column from that type
                //
                var simplePropertyRef = (SimplePropertyRef)innerProperty;
                if (simplePropertyRef != null)
                {
                    var innerType     = simplePropertyRef.Property.TypeUsage;
                    var innerTypeInfo = GetTypeInfo(innerType);
                    result = innerTypeInfo.RootType.TypeIdType;
                }
                else
                {
                    result = typeInfo.TypeIdType;
                }
            }
            else if (p is EntitySetIdPropertyRef ||
                     p is NullSentinelPropertyRef)
            {
                result = m_intType;
            }
            else if (p is RelPropertyRef)
            {
                result = ((RelPropertyRef)p).Property.ToEnd.TypeUsage;
            }
            else
            {
                var simpleP = p as SimplePropertyRef;
                if (simpleP != null)
                {
                    result = md.Helper.GetModelTypeUsage(simpleP.Property);
                }
            }

            result = GetNewType(result);
            PlanCompiler.Assert(null != result, "unrecognized property type?");
            return(result);
        }
Пример #4
0
 protected TypeInfo(TypeUsage type, TypeInfo superType)
 {
     this.m_type = type;
     this.m_immediateSubTypes = new List <TypeInfo>();
     this.m_superType         = superType;
     if (superType == null)
     {
         return;
     }
     superType.m_immediateSubTypes.Add(this);
     this.m_rootType = superType.RootType;
 }
Пример #5
0
 protected TypeInfo(md.TypeUsage type, TypeInfo superType)
 {
     m_type = type;
     m_immediateSubTypes = new List<TypeInfo>();
     m_superType = superType;
     if (superType != null)
     {
         // Add myself to my supertype's list of subtypes
         superType.m_immediateSubTypes.Add(this);
         // my supertype's root type is mine as well
         m_rootType = superType.RootType;
     }
 }
Пример #6
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>
        /// <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;
        }
Пример #7
0
 protected TypeInfo(md.TypeUsage type, TypeInfo superType)
 {
     m_type = type;
     m_immediateSubTypes = new List <TypeInfo>();
     m_superType         = superType;
     if (superType != null)
     {
         // Add myself to my supertype's list of subtypes
         superType.m_immediateSubTypes.Add(this);
         // my supertype's root type is mine as well
         m_rootType = superType.RootType;
     }
 }
Пример #8
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);
        }
Пример #9
0
        private void CreateFlattenedRecordType(RootTypeInfo type)
        {
            bool flag = TypeSemantics.IsEntityType(type.Type) && type.ImmediateSubTypes.Count == 0;
            List <KeyValuePair <string, TypeUsage> > keyValuePairList = new List <KeyValuePair <string, TypeUsage> >();
            HashSet <string> stringSet = new HashSet <string>();
            int num = 0;

            foreach (PropertyRef propertyRef in type.PropertyRefList)
            {
                string key = (string)null;
                if (flag)
                {
                    SimplePropertyRef simplePropertyRef = propertyRef as SimplePropertyRef;
                    if (simplePropertyRef != null)
                    {
                        key = simplePropertyRef.Property.Name;
                    }
                }
                if (key == null)
                {
                    key = "F" + num.ToString((IFormatProvider)CultureInfo.InvariantCulture);
                    ++num;
                }
                while (stringSet.Contains(key))
                {
                    key = "F" + num.ToString((IFormatProvider)CultureInfo.InvariantCulture);
                    ++num;
                }
                TypeUsage propertyType = this.GetPropertyType(type, propertyRef);
                keyValuePairList.Add(new KeyValuePair <string, TypeUsage>(key, propertyType));
                stringSet.Add(key);
            }
            type.FlattenedType = TypeHelpers.CreateRowType((IEnumerable <KeyValuePair <string, TypeUsage> >)keyValuePairList);
            IEnumerator <PropertyRef> enumerator = type.PropertyRefList.GetEnumerator();

            foreach (EdmProperty property in type.FlattenedType.Properties)
            {
                if (!enumerator.MoveNext())
                {
                    System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(false, "property refs count and flattened type member count mismatch?");
                }
                type.AddPropertyMapping(enumerator.Current, property);
            }
        }
Пример #10
0
        private void ExplodeRootStructuredTypeHelper(TypeInfo typeInfo)
        {
            RootTypeInfo rootType = typeInfo.RootType;
            RefType      type;
            IEnumerable  enumerable;

            if (TypeHelpers.TryGetEdmType <RefType>(typeInfo.Type, out type))
            {
                if (!typeInfo.IsRootType)
                {
                    return;
                }
                enumerable = (IEnumerable)type.ElementType.KeyMembers;
            }
            else
            {
                enumerable = TypeHelpers.GetDeclaredStructuralMembers(typeInfo.Type);
            }
            foreach (EdmMember edmMember in enumerable)
            {
                TypeInfo typeInfo1 = this.ExplodeType(edmMember.TypeUsage);
                if (typeInfo1 == null)
                {
                    rootType.AddPropertyRef((PropertyRef) new SimplePropertyRef(edmMember));
                }
                else
                {
                    foreach (PropertyRef propertyRef in typeInfo1.PropertyRefList)
                    {
                        rootType.AddPropertyRef(propertyRef.CreateNestedPropertyRef(edmMember));
                    }
                }
            }
            foreach (TypeInfo immediateSubType in typeInfo.ImmediateSubTypes)
            {
                this.ExplodeRootStructuredTypeHelper(immediateSubType);
            }
        }
Пример #11
0
        private TypeUsage GetPropertyType(RootTypeInfo typeInfo, PropertyRef p)
        {
            TypeUsage   type        = (TypeUsage)null;
            PropertyRef propertyRef = (PropertyRef)null;

            while (p is NestedPropertyRef)
            {
                NestedPropertyRef nestedPropertyRef = (NestedPropertyRef)p;
                p           = nestedPropertyRef.OuterProperty;
                propertyRef = nestedPropertyRef.InnerProperty;
            }
            if (p is TypeIdPropertyRef)
            {
                SimplePropertyRef simplePropertyRef = (SimplePropertyRef)propertyRef;
                type = simplePropertyRef == null ? typeInfo.TypeIdType : this.GetTypeInfo(simplePropertyRef.Property.TypeUsage).RootType.TypeIdType;
            }
            else if (p is EntitySetIdPropertyRef || p is NullSentinelPropertyRef)
            {
                type = this.m_intType;
            }
            else if (p is RelPropertyRef)
            {
                type = ((RelPropertyRef)p).Property.ToEnd.TypeUsage;
            }
            else
            {
                SimplePropertyRef simplePropertyRef = p as SimplePropertyRef;
                if (simplePropertyRef != null)
                {
                    type = Helper.GetModelTypeUsage(simplePropertyRef.Property);
                }
            }
            TypeUsage newType = this.GetNewType(type);

            System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(null != newType, "unrecognized property type?");
            return(newType);
        }
        private void CreateFlattenedRecordType(RootTypeInfo type)
        {
            //
            // If this type corresponds to an entity type, and that entity type
            // has no subtypes, and that that entity type has no complex properties
            // then simply use the name from that property
            //
            bool usePropertyNamesFromUnderlyingType;

            if (md.TypeSemantics.IsEntityType(type.Type)
                &&
                type.ImmediateSubTypes.Count == 0)
            {
                usePropertyNamesFromUnderlyingType = true;
            }
            else
            {
                usePropertyNamesFromUnderlyingType = false;
            }

            // Build the record type
            var fieldList   = new List <KeyValuePair <string, md.TypeUsage> >();
            var fieldNames  = new HashSet <string>();
            var nextFieldId = 0;

            foreach (var p in type.PropertyRefList)
            {
                string fieldName = null;
                if (usePropertyNamesFromUnderlyingType)
                {
                    var simpleP = p as SimplePropertyRef;
                    if (simpleP != null)
                    {
                        fieldName = simpleP.Property.Name;
                    }
                }

                if (fieldName == null)
                {
                    fieldName = "F" + nextFieldId.ToString(CultureInfo.InvariantCulture);
                    nextFieldId++;
                }

                // Deal with collisions
                while (fieldNames.Contains(fieldName))
                {
                    fieldName = "F" + nextFieldId.ToString(CultureInfo.InvariantCulture);
                    nextFieldId++;
                }

                var propertyType = GetPropertyType(type, p);
                fieldList.Add(new KeyValuePair <string, md.TypeUsage>(fieldName, propertyType));
                fieldNames.Add(fieldName);
            }

            type.FlattenedType = TypeHelpers.CreateRowType(fieldList);

            // Now build up the property map
            var origProps = type.PropertyRefList.GetEnumerator();

            foreach (var p in type.FlattenedType.Properties)
            {
                if (!origProps.MoveNext())
                {
                    PlanCompiler.Assert(false, "property refs count and flattened type member count mismatch?");
                }
                type.AddPropertyMapping(origProps.Current, p);
            }
        }
Пример #13
0
        private void CreateFlattenedRecordType(RootTypeInfo type)
        {
            //
            // If this type corresponds to an entity type, and that entity type
            // has no subtypes, and that that entity type has no complex properties
            // then simply use the name from that property
            //
            bool usePropertyNamesFromUnderlyingType;
            if (md.TypeSemantics.IsEntityType(type.Type)
                &&
                type.ImmediateSubTypes.Count == 0)
            {
                usePropertyNamesFromUnderlyingType = true;
            }
            else
            {
                usePropertyNamesFromUnderlyingType = false;
            }

            // Build the record type
            var fieldList = new List<KeyValuePair<string, md.TypeUsage>>();
            var fieldNames = new HashSet<string>();
            var nextFieldId = 0;
            foreach (var p in type.PropertyRefList)
            {
                string fieldName = null;
                if (usePropertyNamesFromUnderlyingType)
                {
                    var simpleP = p as SimplePropertyRef;
                    if (simpleP != null)
                    {
                        fieldName = simpleP.Property.Name;
                    }
                }

                if (fieldName == null)
                {
                    fieldName = "F" + nextFieldId.ToString(CultureInfo.InvariantCulture);
                    nextFieldId++;
                }

                // Deal with collisions
                while (fieldNames.Contains(fieldName))
                {
                    fieldName = "F" + nextFieldId.ToString(CultureInfo.InvariantCulture);
                    nextFieldId++;
                }

                var propertyType = GetPropertyType(type, p);
                fieldList.Add(new KeyValuePair<string, md.TypeUsage>(fieldName, propertyType));
                fieldNames.Add(fieldName);
            }

            type.FlattenedType = TypeHelpers.CreateRowType(fieldList);

            // Now build up the property map
            var origProps = type.PropertyRefList.GetEnumerator();
            foreach (var p in type.FlattenedType.Properties)
            {
                if (!origProps.MoveNext())
                {
                    PlanCompiler.Assert(false, "property refs count and flattened type member count mismatch?");
                }
                type.AddPropertyMapping(origProps.Current, p);
            }
        }
Пример #14
0
        // <summary>
        // "Explode" a root type. (ie) add each member of the type to a flat list of
        // members for the supertype.
        // Type explosion works in a DFS style model. We first walk through the
        // list of properties for the current type, and "flatten" out the properties
        // that are themselves "structured". We then target each subtype (recursively)
        // and perform the same kind of processing.
        // Consider a very simple case:
        // Q = (z1 int, z2 date)
        // Q2: Q = (z3 string)  -- Q2 is a subtype of Q
        // T = (a int, b Q, c date)
        // S: T = (d int)  -- read as S is a subtype of T
        // The result of flattening T (and S) will be
        // (a int, b.z1 int, b.z2 date, b.z3 string, c date, d int)
        // </summary>
        // <param name="rootType"> the root type to explode </param>
        private void ExplodeRootStructuredType(RootTypeInfo rootType)
        {
            // Already done??
            if (rootType.FlattenedType != null)
            {
                return;
            }

            //
            // Special handling for root types. Add any special
            // properties that are needed - TypeId, EntitySetId, etc
            //
            if (NeedsTypeIdProperty(rootType))
            {
                rootType.AddPropertyRef(TypeIdPropertyRef.Instance);
                // check for discriminator map; if one exists, use custom discriminator member; otherwise, use default
                if (null != rootType.DiscriminatorMap)
                {
                    rootType.TypeIdKind = TypeIdKind.UserSpecified;
                    rootType.TypeIdType = md.Helper.GetModelTypeUsage(rootType.DiscriminatorMap.DiscriminatorProperty);
                }
                else
                {
                    rootType.TypeIdKind = TypeIdKind.Generated;
                    rootType.TypeIdType = m_stringType;
                }
            }
            if (NeedsEntitySetIdProperty(rootType))
            {
                rootType.AddPropertyRef(EntitySetIdPropertyRef.Instance);
            }
            if (NeedsNullSentinelProperty(rootType))
            {
                rootType.AddPropertyRef(NullSentinelPropertyRef.Instance);
            }

            //
            // Then add members from each type in the hierarchy (including 
            // the root type)
            //
            ExplodeRootStructuredTypeHelper(rootType);

            //
            // For entity types, add all the rel-properties now. Note that rel-properties
            // are added after the regular properties of all subtypes
            //
            if (md.TypeSemantics.IsEntityType(rootType.Type))
            {
                AddRelProperties(rootType);
            }

            //
            // We've now gotten all the relevant properties
            // Now let's create a new record type
            //
            CreateFlattenedRecordType(rootType);
        }
Пример #15
0
        private md.TypeUsage GetPropertyType(RootTypeInfo typeInfo, PropertyRef p)
        {
            md.TypeUsage result = null;

            PropertyRef innerProperty = null;
            // Get the "leaf" property first
            while (p is NestedPropertyRef)
            {
                var npr = (NestedPropertyRef)p;
                p = npr.OuterProperty;
                innerProperty = npr.InnerProperty;
            }

            if (p is TypeIdPropertyRef)
            {
                //
                // Get to the innermost type that specifies this typeid (the entity type),
                // get the datatype for the typeid column from that type
                //
                var simplePropertyRef = (SimplePropertyRef)innerProperty;
                if (simplePropertyRef != null)
                {
                    var innerType = simplePropertyRef.Property.TypeUsage;
                    var innerTypeInfo = GetTypeInfo(innerType);
                    result = innerTypeInfo.RootType.TypeIdType;
                }
                else
                {
                    result = typeInfo.TypeIdType;
                }
            }
            else if (p is EntitySetIdPropertyRef
                     || p is NullSentinelPropertyRef)
            {
                result = m_intType;
            }
            else if (p is RelPropertyRef)
            {
                result = ((RelPropertyRef)p).Property.ToEnd.TypeUsage;
            }
            else
            {
                var simpleP = p as SimplePropertyRef;
                if (simpleP != null)
                {
                    result = md.Helper.GetModelTypeUsage(simpleP.Property);
                }
            }

            result = GetNewType(result);
            PlanCompiler.Assert(null != result, "unrecognized property type?");
            return result;
        }