예제 #1
0
 /// <summary>
 /// basic constructor
 /// </summary>
 /// <param name="outputVars">List of outputs from this Op</param>
 /// <param name="columnMap">column map that describes the result to be shaped</param>
 internal PhysicalProjectOp(VarList outputVars, SimpleCollectionColumnMap columnMap)
     : this()
 {
     Debug.Assert(null != columnMap, "null columnMap?");
     m_outputVars = outputVars;
     m_columnMap  = columnMap;
 }
        /// <summary>
        /// SimpleCollectionColumnMap
        /// </summary>
        /// <param name="columnMap"></param>
        /// <param name="replacementVarMap"></param>
        /// <returns></returns>
        internal override ColumnMap Visit(SimpleCollectionColumnMap columnMap, VarMap replacementVarMap)
        {
            ColumnMap newElementColumnMap = columnMap.Element.Accept(this, replacementVarMap);

            SimpleColumnMap[] newKeys        = VisitList(columnMap.Keys, replacementVarMap);
            SimpleColumnMap[] newForeignKeys = VisitList(columnMap.ForeignKeys, replacementVarMap);
            return(new SimpleCollectionColumnMap(columnMap.Type, columnMap.Name, newElementColumnMap, newKeys, newForeignKeys));
        }
예제 #3
0
 internal virtual void Visit(SimpleCollectionColumnMap columnMap, TArgType arg)
 {
     foreach (SimpleColumnMap fk in columnMap.ForeignKeys)
     {
         fk.Accept(this, arg);
     }
     foreach (SimpleColumnMap k in columnMap.Keys)
     {
         k.Accept(this, arg);
     }
     columnMap.Element.Accept(this, arg);
 }
예제 #4
0
        /// <summary>
        /// Creates a column map for the given reader and function mapping.
        /// </summary>
        internal static CollectionColumnMap CreateFunctionImportStructuralTypeColumnMap(DbDataReader storeDataReader, FunctionImportMappingNonComposable mapping, int resultSetIndex, EntitySet entitySet, StructuralType baseStructuralType)
        {
            FunctionImportStructuralTypeMappingKB resultMapping = mapping.GetResultMapping(resultSetIndex);

            Debug.Assert(resultMapping != null);
            if (resultMapping.NormalizedEntityTypeMappings.Count == 0) // no explicit mapping; use default non-polymorphic reader
            {
                // if there is no mapping, create default mapping to root entity type or complex type
                Debug.Assert(!baseStructuralType.Abstract, "mapping loader must verify abstract types have explicit mapping");

                return(CreateColumnMapFromReaderAndType(storeDataReader, baseStructuralType, entitySet, resultMapping.ReturnTypeColumnsRenameMapping));
            }

            // the section below deals with the polymorphic entity type mapping for return type
            EntityType baseEntityType = baseStructuralType as EntityType;

            Debug.Assert(null != baseEntityType, "We should have entity type here");

            // Generate column maps for all discriminators
            ScalarColumnMap[] discriminatorColumns = CreateDiscriminatorColumnMaps(storeDataReader, mapping, resultSetIndex);

            // Generate default maps for all mapped entity types
            var mappedEntityTypes = new HashSet <EntityType>(resultMapping.MappedEntityTypes);

            mappedEntityTypes.Add(baseEntityType); // make sure the base type is represented
            Dictionary <EntityType, TypedColumnMap> typeChoices = new Dictionary <EntityType, TypedColumnMap>(mappedEntityTypes.Count);

            ColumnMap[] baseTypeColumnMaps = null;
            foreach (EntityType entityType in mappedEntityTypes)
            {
                ColumnMap[]     propertyColumnMaps = GetColumnMapsForType(storeDataReader, entityType, resultMapping.ReturnTypeColumnsRenameMapping);
                EntityColumnMap entityColumnMap    = CreateEntityTypeElementColumnMap(storeDataReader, entityType, entitySet, propertyColumnMaps, resultMapping.ReturnTypeColumnsRenameMapping);
                if (!entityType.Abstract)
                {
                    typeChoices.Add(entityType, entityColumnMap);
                }
                if (entityType == baseStructuralType)
                {
                    baseTypeColumnMaps = propertyColumnMaps;
                }
            }

            // NOTE: We don't have a null sentinel here, because the stored proc won't
            //       return one anyway; we'll just presume the data's always there.
            MultipleDiscriminatorPolymorphicColumnMap polymorphicMap = new MultipleDiscriminatorPolymorphicColumnMap(TypeUsage.Create(baseStructuralType), baseStructuralType.Name, baseTypeColumnMaps, discriminatorColumns, typeChoices, (object[] discriminatorValues) => mapping.Discriminate(discriminatorValues, resultSetIndex));
            CollectionColumnMap collection = new SimpleCollectionColumnMap(baseStructuralType.GetCollectionType().TypeUsage, baseStructuralType.Name, polymorphicMap, null, null);

            return(collection);
        }
예제 #5
0
        /// <summary>
        /// Copies a PhysicalProjectOp
        /// </summary>
        /// <param name="op"></param>
        /// <param name="n"></param>
        /// <returns></returns>
        public override Node Visit(PhysicalProjectOp op, Node n)
        {
            // Visit the Node's children and map their Vars
            List <Node> children = ProcessChildren(n);

            // Copy the ProjectOp's VarSet
            VarList newVarList = Copy(op.Outputs);

            SimpleCollectionColumnMap newColumnMap = Copy(op.ColumnMap) as SimpleCollectionColumnMap;

            Debug.Assert(newColumnMap != null, "Coping of a physical project's columnMap did not return a SimpleCollectionColumnMap");
            // Create a new ProjectOp based on the copied VarSet
            PhysicalProjectOp newProject = m_destCmd.CreatePhysicalProjectOp(newVarList, newColumnMap);

            // Return a new Node that references the copied ProjectOp and has the copied child Nodes as its children
            return(m_destCmd.CreateNode(newProject, children));
        }
예제 #6
0
        /// <summary>
        /// Build the collectionColumnMap from a store datareader, a type and an entitySet.
        /// </summary>
        /// <param name="storeDataReader"></param>
        /// <param name="edmType"></param>
        /// <param name="entitySet"></param>
        /// <returns></returns>
        internal static CollectionColumnMap CreateColumnMapFromReaderAndType(DbDataReader storeDataReader, EdmType edmType, EntitySet entitySet, Dictionary <string, FunctionImportReturnTypeStructuralTypeColumnRenameMapping> renameList)
        {
            Debug.Assert(Helper.IsEntityType(edmType) || null == entitySet, "The specified non-null EntitySet is incompatible with the EDM type specified.");

            // Next, build the ColumnMap directly from the edmType and entitySet provided.
            ColumnMap[] propertyColumnMaps = GetColumnMapsForType(storeDataReader, edmType, renameList);
            ColumnMap   elementColumnMap   = null;

            // NOTE: We don't have a null sentinel here, because the stored proc won't
            //       return one anyway; we'll just presume the data's always there.
            if (Helper.IsRowType(edmType))
            {
                elementColumnMap = new RecordColumnMap(TypeUsage.Create(edmType), edmType.Name, propertyColumnMaps, null);
            }
            else if (Helper.IsComplexType(edmType))
            {
                elementColumnMap = new ComplexTypeColumnMap(TypeUsage.Create(edmType), edmType.Name, propertyColumnMaps, null);
            }
            else if (Helper.IsScalarType(edmType))
            {
                if (storeDataReader.FieldCount != 1)
                {
                    throw EntityUtil.CommandExecutionDataReaderFieldCountForScalarType();
                }
                elementColumnMap = new ScalarColumnMap(TypeUsage.Create(edmType), edmType.Name, 0, 0);
            }
            else if (Helper.IsEntityType(edmType))
            {
                elementColumnMap = CreateEntityTypeElementColumnMap(storeDataReader, edmType, entitySet, propertyColumnMaps, null /*renameList*/);
            }
            else
            {
                Debug.Assert(false, "unexpected edmType?");
            }
            CollectionColumnMap collection = new SimpleCollectionColumnMap(edmType.GetCollectionType().TypeUsage, edmType.Name, elementColumnMap, null, null);

            return(collection);
        }
예제 #7
0
        /// <summary>
        /// Requires: a public type with a public, default constructor. Returns a column map initializing the type
        /// and all properties of the type with a public setter taking a primitive type and having a corresponding
        /// column in the reader.
        /// </summary>
        internal static CollectionColumnMap CreateColumnMapFromReaderAndClrType(DbDataReader reader, Type type, MetadataWorkspace workspace)
        {
            Debug.Assert(null != reader);
            Debug.Assert(null != type);
            Debug.Assert(null != workspace);

            // we require a default constructor
            ConstructorInfo constructor = type.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
                                                              null, Type.EmptyTypes, null);

            if (type.IsAbstract || (null == constructor && !type.IsValueType))
            {
                throw EntityUtil.InvalidOperation(
                          Strings.ObjectContext_InvalidTypeForStoreQuery(type));
            }

            // build a LINQ expression used by result assembly to create results
            var memberInfo = new List <Tuple <MemberAssignment, int, EdmProperty> >();

            foreach (PropertyInfo prop in type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
            {
                // for enums unwrap the type if nullable
                var  propertyUnderlyingType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
                Type propType = propertyUnderlyingType.IsEnum ? propertyUnderlyingType.GetEnumUnderlyingType() : prop.PropertyType;

                EdmType modelType;
                int     ordinal;
                if (TryGetColumnOrdinalFromReader(reader, prop.Name, out ordinal) &&
                    MetadataHelper.TryDetermineCSpaceModelType(propType, workspace, out modelType) &&
                    (Helper.IsScalarType(modelType)) &&
                    prop.CanWrite && prop.GetIndexParameters().Length == 0 && null != prop.GetSetMethod(/* nonPublic */ true))
                {
                    memberInfo.Add(Tuple.Create(
                                       Expression.Bind(prop, Expression.Parameter(prop.PropertyType, "placeholder")),
                                       ordinal,
                                       new EdmProperty(prop.Name, TypeUsage.Create(modelType))));
                }
            }
            // initialize members in the order in which they appear in the reader
            MemberInfo[]    members         = new MemberInfo[memberInfo.Count];
            MemberBinding[] memberBindings  = new MemberBinding[memberInfo.Count];
            ColumnMap[]     propertyMaps    = new ColumnMap[memberInfo.Count];
            EdmProperty[]   modelProperties = new EdmProperty[memberInfo.Count];
            int             i = 0;

            foreach (var memberGroup in memberInfo.GroupBy(tuple => tuple.Item2).OrderBy(tuple => tuple.Key))
            {
                // make sure that a single column isn't contributing to multiple properties
                if (memberGroup.Count() != 1)
                {
                    throw EntityUtil.InvalidOperation(Strings.ObjectContext_TwoPropertiesMappedToSameColumn(
                                                          reader.GetName(memberGroup.Key),
                                                          String.Join(", ", memberGroup.Select(tuple => tuple.Item3.Name).ToArray())));
                }

                var member = memberGroup.Single();
                MemberAssignment assignment = member.Item1;
                int         ordinal         = member.Item2;
                EdmProperty modelProp       = member.Item3;

                members[i]         = assignment.Member;
                memberBindings[i]  = assignment;
                propertyMaps[i]    = new ScalarColumnMap(modelProp.TypeUsage, modelProp.Name, 0, ordinal);
                modelProperties[i] = modelProp;
                i++;
            }
            NewExpression newExpr = null == constructor?Expression.New(type) : Expression.New(constructor);

            MemberInitExpression init         = Expression.MemberInit(newExpr, memberBindings);
            InitializerMetadata  initMetadata = InitializerMetadata.CreateProjectionInitializer(
                (EdmItemCollection)workspace.GetItemCollection(DataSpace.CSpace), init, members);

            // column map (a collection of rows with InitializerMetadata markup)
            RowType         rowType = new RowType(modelProperties, initMetadata);
            RecordColumnMap rowMap  = new RecordColumnMap(TypeUsage.Create(rowType),
                                                          "DefaultTypeProjection", propertyMaps, null);
            CollectionColumnMap collectionMap = new SimpleCollectionColumnMap(rowType.GetCollectionType().TypeUsage,
                                                                              rowType.Name, rowMap, null, null);

            return(collectionMap);
        }
예제 #8
0
파일: Dump.cs 프로젝트: dox0/DotNet471RS3
 /// <summary>
 /// SimpleCollectionColumnMap
 /// </summary>
 /// <param name="columnMap"></param>
 /// <param name="dumper"></param>
 /// <returns></returns>
 internal override void Visit(SimpleCollectionColumnMap columnMap, Dump dumper)
 {
     using (new AutoXml(dumper, "SimpleCollection", GetAttributes(columnMap))) {
         DumpCollection(columnMap, dumper);
     }
 }
예제 #9
0
 internal abstract TResultType Visit(SimpleCollectionColumnMap columnMap, TArgType arg);