Exemple #1
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="type">datatype of column</param>
        /// <param name="name">column name</param>
        /// <param name="elementMap">column map for collection element</param>
        /// <param name="keys">List of keys</param>
        /// <param name="foreignKeys">List of foreign keys</param>
        internal CollectionColumnMap(md.TypeUsage type, string name, ColumnMap elementMap, SimpleColumnMap[] keys, SimpleColumnMap[] foreignKeys)
            : base(type, name)
        {
            Debug.Assert(elementMap != null, "Must specify column map for element");

            m_element     = elementMap;
            m_keys        = keys ?? new SimpleColumnMap[0];
            m_foreignKeys = foreignKeys ?? new SimpleColumnMap[0];
        }
Exemple #2
0
 internal CollectionInfo(Var collectionVar, ColumnMap columnMap, VarList flattenedElementVars, VarVec keys, List <InternalTrees.SortKey> sortKeys, object discriminatorValue)
 {
     m_collectionVar        = collectionVar;
     m_columnMap            = columnMap;
     m_flattenedElementVars = flattenedElementVars;
     m_keys               = keys;
     m_sortKeys           = sortKeys;
     m_discriminatorValue = discriminatorValue;
 }
Exemple #3
0
 /// <summary>
 /// Internal constructor
 /// </summary>
 /// <param name="type">Column datatype</param>
 /// <param name="name">column name</param>
 /// <param name="elementMap">column map for collection element</param>
 /// <param name="keys">Keys for the collection</param>
 /// <param name="foreignKeys">Foreign keys for the collection</param>
 /// <param name="discriminator">Discriminator column map</param>
 /// <param name="discriminatorValue">Discriminator value</param>
 internal DiscriminatedCollectionColumnMap(md.TypeUsage type, string name,
                                           ColumnMap elementMap,
                                           SimpleColumnMap[] keys,
                                           SimpleColumnMap[] foreignKeys,
                                           SimpleColumnMap discriminator,
                                           object discriminatorValue)
     : base(type, name, elementMap, keys, foreignKeys)
 {
     Debug.Assert(discriminator != null, "Must specify a column map for the collection discriminator");
     Debug.Assert(discriminatorValue != null, "Must specify a discriminator value");
     m_discriminator      = discriminator;
     m_discriminatorValue = discriminatorValue;
 }
Exemple #4
0
        internal virtual void Visit(ComplexTypeColumnMap columnMap, TArgType arg)
        {
            ColumnMap nullSentinel = columnMap.NullSentinel;

            if (null != nullSentinel)
            {
                nullSentinel.Accept(this, arg);
            }
            foreach (ColumnMap p in columnMap.Properties)
            {
                p.Accept(this, arg);
            }
        }
Exemple #5
0
        private Node VisitNestOp(Node n)
        {
            NestBaseOp         op    = n.Op as NestBaseOp;
            SingleStreamNestOp ssnOp = op as SingleStreamNestOp;

            Debug.Assert(op != null);

            // Visit the Node's children and map their Vars
            List <Node> newChildren = ProcessChildren(n);

            Var newDiscriminator = null;

            if (ssnOp != null)
            {
                newDiscriminator = GetMappedVar(ssnOp.Discriminator);
            }
            List <CollectionInfo> newCollectionInfoList = new List <CollectionInfo>();

            foreach (CollectionInfo ci in op.CollectionInfo)
            {
                ColumnMap newColumnMap = Copy(ci.ColumnMap);

                Var newCollectionVar = m_destCmd.CreateComputedVar(ci.CollectionVar.Type);
                SetMappedVar(ci.CollectionVar, newCollectionVar);

                VarList        newFlattendElementVars = Copy(ci.FlattenedElementVars);
                VarVec         newKeys           = Copy(ci.Keys);
                List <SortKey> newSortKeys       = Copy(ci.SortKeys);
                CollectionInfo newCollectionInfo = Command.CreateCollectionInfo(newCollectionVar, newColumnMap, newFlattendElementVars, newKeys, newSortKeys, ci.DiscriminatorValue);
                newCollectionInfoList.Add(newCollectionInfo);
            }

            VarVec newOutputs = Copy(op.Outputs);

            NestBaseOp     newOp             = null;
            List <SortKey> newPrefixSortKeys = Copy(op.PrefixSortKeys);

            if (ssnOp != null)
            {
                VarVec newKeys = Copy(ssnOp.Keys);
                // Copy the SortOp's SortKeys
                List <SortKey> newPostfixSortKeys = Copy(ssnOp.PostfixSortKeys);
                newOp = m_destCmd.CreateSingleStreamNestOp(newKeys, newPrefixSortKeys, newPostfixSortKeys, newOutputs, newCollectionInfoList, newDiscriminator);
            }
            else
            {
                newOp = m_destCmd.CreateMultiStreamNestOp(newPrefixSortKeys, newOutputs, newCollectionInfoList);
            }

            return(m_destCmd.CreateNode(newOp, newChildren));
        }
Exemple #6
0
        static internal string ToXml(ColumnMap columnMap)
        {
            MemoryStream stream = new MemoryStream();

            using (Dump dumper = new Dump(stream)) {
                // Just in case the node we're provided doesn't dump as XML, we'll always stick
                // an XML wrapper around it -- this happens when we're dumping scalarOps, for
                // example, and it's unfortunate if you can't debug them using a dump...
                using (new AutoXml(dumper, "columnMap")) {
                    columnMap.Accept(ColumnMapDumper.Instance, dumper);
                }
            }

            return(DefaultEncoding.GetString(stream.ToArray()));
        }
        /// <summary>
        /// Build the entityColumnMap from a store datareader, a type and an entitySet and
        /// a list ofproperties.
        /// </summary>
        /// <param name="storeDataReader"></param>
        /// <param name="edmType"></param>
        /// <param name="entitySet"></param>
        /// <param name="propertyColumnMaps"></param>
        /// <returns></returns>
        private static EntityColumnMap CreateEntityTypeElementColumnMap(
            DbDataReader storeDataReader, EdmType edmType, EntitySet entitySet,
            ColumnMap[] propertyColumnMaps, Dictionary <string, FunctionImportReturnTypeStructuralTypeColumnRenameMapping> renameList)
        {
            EntityType entityType = (EntityType)edmType;

            // The tricky part here is
            // that the KeyColumns list must point at the same ColumnMap(s) that
            // the properties list points to, so we build a quick array of
            // ColumnMap(s) that are indexed by their ordinal; then we can walk
            // the list of keyMembers, and find the ordinal in the reader, and
            // pick the same ColumnMap for it.

            // Build the ordinal -> ColumnMap index
            ColumnMap[] ordinalToColumnMap = new ColumnMap[storeDataReader.FieldCount];

            foreach (ColumnMap propertyColumnMap in propertyColumnMaps)
            {
                int ordinal = ((ScalarColumnMap)propertyColumnMap).ColumnPos;
                ordinalToColumnMap[ordinal] = propertyColumnMap;
            }

            // Now build the list of KeyColumns;
            IList <EdmMember> keyMembers = entityType.KeyMembers;

            SimpleColumnMap[] keyColumns = new SimpleColumnMap[keyMembers.Count];

            int keyMemberIndex = 0;

            foreach (EdmMember keyMember in keyMembers)
            {
                int keyOrdinal = GetMemberOrdinalFromReader(storeDataReader, keyMember, edmType, renameList);

                Debug.Assert(keyOrdinal >= 0, "keyMember for entity is not found by name in the data reader?");

                ColumnMap keyColumnMap = ordinalToColumnMap[keyOrdinal];

                Debug.Assert(null != keyColumnMap, "keyMember for entity isn't in properties collection for the entity?");
                keyColumns[keyMemberIndex] = (SimpleColumnMap)keyColumnMap;
                keyMemberIndex++;
            }

            SimpleEntityIdentity entityIdentity = new SimpleEntityIdentity(entitySet, keyColumns);

            EntityColumnMap result = new EntityColumnMap(TypeUsage.Create(edmType), edmType.Name, propertyColumnMaps, entityIdentity);

            return(result);
        }
        /// <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);
        }
        /// <summary>
        /// For a given edmType, build an array of scalarColumnMaps that map to the columns
        /// in the store datareader provided.  Note that we're hooking things up by name, not
        /// by ordinal position.
        /// </summary>
        /// <param name="storeDataReader"></param>
        /// <param name="edmType"></param>
        /// <returns></returns>
        private static ColumnMap[] GetColumnMapsForType(DbDataReader storeDataReader, EdmType edmType, Dictionary <string, FunctionImportReturnTypeStructuralTypeColumnRenameMapping> renameList)
        {
            // First get the list of properties; NOTE: we need to hook up the column by name,
            // not by position.
            IBaseList <EdmMember> members = TypeHelpers.GetAllStructuralMembers(edmType);

            ColumnMap[] propertyColumnMaps = new ColumnMap[members.Count];

            int index = 0;

            foreach (EdmMember member in members)
            {
                if (!Helper.IsScalarType(member.TypeUsage.EdmType))
                {
                    throw EntityUtil.InvalidOperation(Strings.ADP_InvalidDataReaderUnableToMaterializeNonScalarType(member.Name, member.TypeUsage.EdmType.FullName));
                }

                int ordinal = GetMemberOrdinalFromReader(storeDataReader, member, edmType, renameList);

                propertyColumnMaps[index] = new ScalarColumnMap(member.TypeUsage, member.Name, 0, ordinal);
                index++;
            }
            return(propertyColumnMaps);
        }
Exemple #10
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);
        }
Exemple #11
0
 private ColumnMap Copy(ColumnMap columnMap)
 {
     return(ColumnMapCopier.Copy(columnMap, m_varMap));
 }