Ejemplo n.º 1
0
        private SimplePolymorphicColumnMap CreatePolymorphicColumnMap(
            TypeInfo typeInfo,
            string name)
        {
            Dictionary <object, TypedColumnMap> dictionary = new Dictionary <object, TypedColumnMap>(typeInfo.RootType.DiscriminatorMap == null ? (IEqualityComparer <object>)null : (IEqualityComparer <object>)TrailingSpaceComparer.Instance);
            List <TypedColumnMap> allMaps   = new List <TypedColumnMap>();
            TypeInfo        rootType        = (TypeInfo)typeInfo.RootType;
            SimpleColumnMap typeIdColumnMap = this.CreateTypeIdColumnMap(rootType.TypeIdProperty);

            if (TypeSemantics.IsComplexType(typeInfo.Type))
            {
                this.CreateComplexTypeColumnMap(rootType, name, (ComplexTypeColumnMap)null, dictionary, allMaps);
            }
            else
            {
                this.CreateEntityColumnMap(rootType, name, (EntityColumnMap)null, dictionary, allMaps, true);
            }
            TypedColumnMap typedColumnMap1 = (TypedColumnMap)null;

            foreach (TypedColumnMap typedColumnMap2 in allMaps)
            {
                if (TypeSemantics.IsStructurallyEqual(typedColumnMap2.Type, typeInfo.Type))
                {
                    typedColumnMap1 = typedColumnMap2;
                    break;
                }
            }
            System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(null != typedColumnMap1, "Didn't find requested type in polymorphic type hierarchy?");
            return(new SimplePolymorphicColumnMap(typeInfo.Type, name, typedColumnMap1.Properties, typeIdColumnMap, dictionary));
        }
Ejemplo n.º 2
0
        /// <summary>
        /// SimplePolymorphicColumnMap
        /// </summary>
        /// <param name="columnMap"></param>
        /// <param name="translationDelegate"></param>
        /// <returns></returns>
        internal override ColumnMap Visit(SimplePolymorphicColumnMap columnMap, ColumnMapTranslatorTranslationDelegate translationDelegate)
        {
            ColumnMap newTypeDiscriminator = columnMap.TypeDiscriminator.Accept(this, translationDelegate);

            // NOTE: we're using Copy-On-Write logic to avoid allocation if we don't
            //       need to change things.
            Dictionary <object, TypedColumnMap> newTypeChoices = columnMap.TypeChoices;

            foreach (KeyValuePair <object, TypedColumnMap> kv in columnMap.TypeChoices)
            {
                TypedColumnMap newTypeChoice = (TypedColumnMap)kv.Value.Accept(this, translationDelegate);

                if (newTypeChoice != kv.Value)
                {
                    if (newTypeChoices == columnMap.TypeChoices)
                    {
                        newTypeChoices = new Dictionary <object, TypedColumnMap>(columnMap.TypeChoices);
                    }
                    newTypeChoices[kv.Key] = newTypeChoice;
                }
            }
            VisitList(columnMap.Properties, translationDelegate);

            if (newTypeDiscriminator != columnMap.TypeDiscriminator || newTypeChoices != columnMap.TypeChoices)
            {
                columnMap = new SimplePolymorphicColumnMap(columnMap.Type, columnMap.Name, columnMap.Properties, (SimpleColumnMap)newTypeDiscriminator, newTypeChoices);
            }
            return(translationDelegate(columnMap));
        }
Ejemplo n.º 3
0
        internal override ColumnMap Visit(
            SimplePolymorphicColumnMap columnMap,
            ColumnMapTranslatorTranslationDelegate translationDelegate)
        {
            ColumnMap columnMap1 = columnMap.TypeDiscriminator.Accept <ColumnMap, ColumnMapTranslatorTranslationDelegate>((ColumnMapVisitorWithResults <ColumnMap, ColumnMapTranslatorTranslationDelegate>) this, translationDelegate);
            Dictionary <object, TypedColumnMap> typeChoices = columnMap.TypeChoices;

            foreach (KeyValuePair <object, TypedColumnMap> typeChoice in columnMap.TypeChoices)
            {
                TypedColumnMap typedColumnMap = (TypedColumnMap)typeChoice.Value.Accept <ColumnMap, ColumnMapTranslatorTranslationDelegate>((ColumnMapVisitorWithResults <ColumnMap, ColumnMapTranslatorTranslationDelegate>) this, translationDelegate);
                if (typedColumnMap != typeChoice.Value)
                {
                    if (typeChoices == columnMap.TypeChoices)
                    {
                        typeChoices = new Dictionary <object, TypedColumnMap>((IDictionary <object, TypedColumnMap>)columnMap.TypeChoices);
                    }
                    typeChoices[typeChoice.Key] = typedColumnMap;
                }
            }
            this.VisitList <ColumnMap>(columnMap.Properties, translationDelegate);
            if (columnMap1 != columnMap.TypeDiscriminator || typeChoices != columnMap.TypeChoices)
            {
                columnMap = new SimplePolymorphicColumnMap(columnMap.Type, columnMap.Name, columnMap.Properties, (SimpleColumnMap)columnMap1, typeChoices);
            }
            return(translationDelegate((ColumnMap)columnMap));
        }
        private SimplePolymorphicColumnMap CreatePolymorphicColumnMap(TypeInfo typeInfo, string name)
        {
            // if the typeInfo has a DiscriminatorMap, use TrailingSpaceComparer to ensure that lookups
            // against discriminator values that SQL Server has right-padded (e.g. nchar and char) are properly
            // interpreted
            var discriminatorMap = new Dictionary <object, TypedColumnMap>(
                typeInfo.RootType.DiscriminatorMap == null ? null : TrailingSpaceComparer.Instance);
            // abstract types may not have discriminator values, but may nonetheless be interesting
            var allMaps = new List <TypedColumnMap>();

            // SQLBUDT #433011 -- Polymorphic types must construct column maps
            //                    that map to the entire type hierarchy, so we
            //                    need to use the RootType, not the current type.
            TypeInfo rootTypeInfo = typeInfo.RootType;

            // Get the type discriminant column first
            var typeIdColumnMap = CreateTypeIdColumnMap(rootTypeInfo.TypeIdProperty);

            // Prepare a place for the constructors to put the columns on the base
            // type, as they identify them.
            TypedColumnMap rootTypeColumnMap = null;

            // process complex/entity types appropriately
            // use the same name for the column
            if (md.TypeSemantics.IsComplexType(typeInfo.Type))
            {
                rootTypeColumnMap = CreateComplexTypeColumnMap(rootTypeInfo, name, null, discriminatorMap, allMaps);
            }
            else
            {
                rootTypeColumnMap = CreateEntityColumnMap(rootTypeInfo, name, null, discriminatorMap, allMaps, true);
            }

            // Naturally, nothing is simple; we need to walk the rootTypeColumnMap hierarchy
            // and find the column map for the type that we are supposed to have as the base
            // type of this hierarchy.

            TypedColumnMap baseTypeColumnMap = null;

            foreach (var value in allMaps)
            {
                if (md.TypeSemantics.IsStructurallyEqual(value.Type, typeInfo.Type))
                {
                    baseTypeColumnMap = value;
                    break;
                }
            }
            PlanCompiler.Assert(null != baseTypeColumnMap, "Didn't find requested type in polymorphic type hierarchy?");

            // Create a polymorphic column map
            var result = new SimplePolymorphicColumnMap(
                typeInfo.Type, name, baseTypeColumnMap.Properties, typeIdColumnMap, discriminatorMap);

            return(result);
        }