Пример #1
0
 /// <summary>
 ///     Basic constructor
 /// </summary>
 /// <param name="type"> Column datatype </param>
 /// <param name="name"> column name </param>
 /// <param name="elementMap"> column map for the element of the collection </param>
 /// <param name="keys"> list of key columns </param>
 /// <param name="foreignKeys"> list of foreign key columns </param>
 internal SimpleCollectionColumnMap(
     TypeUsage type, string name,
     ColumnMap elementMap,
     SimpleColumnMap[] keys,
     SimpleColumnMap[] foreignKeys)
     : base(type, name, elementMap, keys, foreignKeys)
 {
 }
        internal virtual CollectionColumnMap CreateColumnMapFromReaderAndClrType(
            DbDataReader reader,
            Type type,
            MetadataWorkspace workspace)
        {
            ConstructorInfo declaredConstructor = type.GetDeclaredConstructor();

            if (type.IsAbstract() || (ConstructorInfo)null == declaredConstructor && !type.IsValueType())
            {
                throw new InvalidOperationException(Strings.ObjectContext_InvalidTypeForStoreQuery((object)type));
            }
            List <Tuple <MemberAssignment, int, EdmProperty> > source1 = new List <Tuple <MemberAssignment, int, EdmProperty> >();

            foreach (PropertyInfo propertyInfo in type.GetInstanceProperties().Select <PropertyInfo, PropertyInfo>((Func <PropertyInfo, PropertyInfo>)(p => p.GetPropertyInfoForSet())))
            {
                Type type1 = Nullable.GetUnderlyingType(propertyInfo.PropertyType);
                if ((object)type1 == null)
                {
                    type1 = propertyInfo.PropertyType;
                }
                Type    type2 = type1;
                Type    type3 = type2.IsEnum() ? type2.GetEnumUnderlyingType() : propertyInfo.PropertyType;
                int     ordinal;
                EdmType modelEdmType;
                if (ColumnMapFactory.TryGetColumnOrdinalFromReader(reader, propertyInfo.Name, out ordinal) && workspace.TryDetermineCSpaceModelType(type3, out modelEdmType) && (Helper.IsScalarType(modelEdmType) && propertyInfo.CanWriteExtended()) && (propertyInfo.GetIndexParameters().Length == 0 && (MethodInfo)null != propertyInfo.Setter()))
                {
                    source1.Add(Tuple.Create <MemberAssignment, int, EdmProperty>(Expression.Bind((MemberInfo)propertyInfo, (Expression)Expression.Parameter(propertyInfo.PropertyType, "placeholder")), ordinal, new EdmProperty(propertyInfo.Name, TypeUsage.Create(modelEdmType))));
                }
            }
            MemberInfo[]    memberInfoArray    = new MemberInfo[source1.Count];
            MemberBinding[] memberBindingArray = new MemberBinding[source1.Count];
            ColumnMap[]     properties         = new ColumnMap[source1.Count];
            EdmProperty[]   edmPropertyArray   = new EdmProperty[source1.Count];
            int             index = 0;

            foreach (IGrouping <int, Tuple <MemberAssignment, int, EdmProperty> > source2 in (IEnumerable <IGrouping <int, Tuple <MemberAssignment, int, EdmProperty> > >)source1.GroupBy <Tuple <MemberAssignment, int, EdmProperty>, int>((Func <Tuple <MemberAssignment, int, EdmProperty>, int>)(tuple => tuple.Item2)).OrderBy <IGrouping <int, Tuple <MemberAssignment, int, EdmProperty> >, int>((Func <IGrouping <int, Tuple <MemberAssignment, int, EdmProperty> >, int>)(tuple => tuple.Key)))
            {
                if (source2.Count <Tuple <MemberAssignment, int, EdmProperty> >() != 1)
                {
                    throw new InvalidOperationException(Strings.ObjectContext_TwoPropertiesMappedToSameColumn((object)reader.GetName(source2.Key), (object)string.Join(", ", source2.Select <Tuple <MemberAssignment, int, EdmProperty>, string>((Func <Tuple <MemberAssignment, int, EdmProperty>, string>)(tuple => tuple.Item3.Name)).ToArray <string>())));
                }
                Tuple <MemberAssignment, int, EdmProperty> tuple1 = source2.Single <Tuple <MemberAssignment, int, EdmProperty> >();
                MemberAssignment memberAssignment = tuple1.Item1;
                int         columnPos             = tuple1.Item2;
                EdmProperty edmProperty           = tuple1.Item3;
                memberInfoArray[index]    = memberAssignment.Member;
                memberBindingArray[index] = (MemberBinding)memberAssignment;
                properties[index]         = (ColumnMap) new ScalarColumnMap(edmProperty.TypeUsage, edmProperty.Name, 0, columnPos);
                edmPropertyArray[index]   = edmProperty;
                ++index;
            }
            MemberInitExpression initExpression        = Expression.MemberInit((ConstructorInfo)null == declaredConstructor ? Expression.New(type) : Expression.New(declaredConstructor), memberBindingArray);
            InitializerMetadata  projectionInitializer = InitializerMetadata.CreateProjectionInitializer((EdmItemCollection)workspace.GetItemCollection(DataSpace.CSpace), initExpression);
            RowType         rowType         = new RowType((IEnumerable <EdmProperty>)edmPropertyArray, projectionInitializer);
            RecordColumnMap recordColumnMap = new RecordColumnMap(TypeUsage.Create((EdmType)rowType), "DefaultTypeProjection", properties, (SimpleColumnMap)null);

            return((CollectionColumnMap) new SimpleCollectionColumnMap(rowType.GetCollectionType().TypeUsage, rowType.Name, (ColumnMap)recordColumnMap, (SimpleColumnMap[])null, (SimpleColumnMap[])null));
        }
Пример #3
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(
            TypeUsage type, string name, ColumnMap elementMap, SimpleColumnMap[] keys, SimpleColumnMap[] foreignKeys)
            : base(type, name)
        {
            DebugCheck.NotNull(elementMap);

            m_element     = elementMap;
            m_keys        = keys ?? new SimpleColumnMap[0];
            m_foreignKeys = foreignKeys ?? new SimpleColumnMap[0];
        }
Пример #4
0
 private static Dictionary <string, object> GetAttributes(ColumnMap columnMap)
 {
     return(new Dictionary <string, object>()
     {
         {
             "Type",
             (object)columnMap.Type.ToString()
         }
     });
 }
Пример #5
0
 internal static CollectionInfo CreateCollectionInfo(
     Var collectionVar,
     ColumnMap columnMap,
     VarList flattenedElementVars,
     VarVec keys,
     List <SortKey> sortKeys,
     object discriminatorValue)
 {
     return(new CollectionInfo(collectionVar, columnMap, flattenedElementVars, keys, sortKeys, discriminatorValue));
 }
Пример #6
0
 internal CollectionInfo(
     Var collectionVar, ColumnMap columnMap, VarList flattenedElementVars, VarVec keys, List <SortKey> sortKeys,
     object discriminatorValue)
 {
     m_collectionVar        = collectionVar;
     m_columnMap            = columnMap;
     m_flattenedElementVars = flattenedElementVars;
     m_keys               = keys;
     m_sortKeys           = sortKeys;
     m_discriminatorValue = discriminatorValue;
 }
 internal CollectionColumnMap(
     TypeUsage type,
     string name,
     ColumnMap elementMap,
     SimpleColumnMap[] keys,
     SimpleColumnMap[] foreignKeys)
     : base(type, name)
 {
     this.m_element     = elementMap;
     this.m_keys        = keys ?? new SimpleColumnMap[0];
     this.m_foreignKeys = foreignKeys ?? new SimpleColumnMap[0];
 }
 internal DiscriminatedCollectionColumnMap(
     TypeUsage type,
     string name,
     ColumnMap elementMap,
     SimpleColumnMap[] keys,
     SimpleColumnMap[] foreignKeys,
     SimpleColumnMap discriminator,
     object discriminatorValue)
     : base(type, name, elementMap, keys, foreignKeys)
 {
     this.m_discriminator      = discriminator;
     this.m_discriminatorValue = discriminatorValue;
 }
Пример #9
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(
     TypeUsage type, string name,
     ColumnMap elementMap,
     SimpleColumnMap[] keys,
     SimpleColumnMap[] foreignKeys,
     SimpleColumnMap discriminator,
     object discriminatorValue)
     : base(type, name, elementMap, keys, foreignKeys)
 {
     DebugCheck.NotNull(discriminator);
     DebugCheck.NotNull(discriminatorValue);
     m_discriminator      = discriminator;
     m_discriminatorValue = discriminatorValue;
 }
Пример #10
0
        // <summary>
        // Build the entityColumnMap from a store datareader, a type and an entitySet and
        // a list of properties.
        // </summary>
        private static EntityColumnMap CreateEntityTypeElementColumnMap(
            DbDataReader storeDataReader, EdmType edmType, EntitySet entitySet,
            ColumnMap[] propertyColumnMaps, Dictionary <string, FunctionImportReturnTypeStructuralTypeColumnRenameMapping> renameList)
        {
            var 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
            var ordinalToColumnMap = new ColumnMap[storeDataReader.FieldCount];

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

            // Now build the list of KeyColumns;
            IList <EdmMember> keyMembers = entityType.KeyMembers;
            var keyColumns = new SimpleColumnMap[keyMembers.Count];

            var keyMemberIndex = 0;

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

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

                var keyColumnMap = ordinalToColumnMap[keyOrdinal];

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

            var entityIdentity = new SimpleEntityIdentity(entitySet, keyColumns);

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

            return(result);
        }
Пример #11
0
        internal static string ToXml(ColumnMap columnMap)
        {
            var stream = new MemoryStream();

            using (var 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()));
        }
Пример #12
0
        // <summary>
        // Build the collectionColumnMap from a store datareader, a type and an entitySet.
        // </summary>
        internal virtual 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.
            var       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 new EntityCommandExecutionException(Strings.ADP_InvalidDataReaderFieldCountForScalarType);
                }
                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);
        }
        private Node VisitNestOp(Node n)
        {
            NestBaseOp         op = n.Op as NestBaseOp;
            SingleStreamNestOp singleStreamNestOp = op as SingleStreamNestOp;
            List <Node>        args = this.ProcessChildren(n);
            Var discriminatorVar    = (Var)null;

            if (singleStreamNestOp != null)
            {
                discriminatorVar = this.GetMappedVar(singleStreamNestOp.Discriminator);
            }
            List <CollectionInfo> collectionInfoList = new List <CollectionInfo>();

            foreach (CollectionInfo collectionInfo1 in op.CollectionInfo)
            {
                ColumnMap columnMap   = this.Copy(collectionInfo1.ColumnMap);
                Var       computedVar = (Var)this.m_destCmd.CreateComputedVar(collectionInfo1.CollectionVar.Type);
                this.SetMappedVar(collectionInfo1.CollectionVar, computedVar);
                VarList        flattenedElementVars = this.Copy(collectionInfo1.FlattenedElementVars);
                VarVec         keys            = this.Copy(collectionInfo1.Keys);
                List <SortKey> sortKeys        = this.Copy(collectionInfo1.SortKeys);
                CollectionInfo collectionInfo2 = Command.CreateCollectionInfo(computedVar, columnMap, flattenedElementVars, keys, sortKeys, collectionInfo1.DiscriminatorValue);
                collectionInfoList.Add(collectionInfo2);
            }
            VarVec         outputVars     = this.Copy(op.Outputs);
            List <SortKey> prefixSortKeys = this.Copy(op.PrefixSortKeys);
            NestBaseOp     nestBaseOp;

            if (singleStreamNestOp != null)
            {
                VarVec         keys            = this.Copy(singleStreamNestOp.Keys);
                List <SortKey> postfixSortKeys = this.Copy(singleStreamNestOp.PostfixSortKeys);
                nestBaseOp = (NestBaseOp)this.m_destCmd.CreateSingleStreamNestOp(keys, prefixSortKeys, postfixSortKeys, outputVars, collectionInfoList, discriminatorVar);
            }
            else
            {
                nestBaseOp = (NestBaseOp)this.m_destCmd.CreateMultiStreamNestOp(prefixSortKeys, outputVars, collectionInfoList);
            }
            return(this.m_destCmd.CreateNode((Op)nestBaseOp, args));
        }
        private static ColumnMap[] GetColumnMapsForType(
            DbDataReader storeDataReader,
            EdmType edmType,
            Dictionary <string, FunctionImportReturnTypeStructuralTypeColumnRenameMapping> renameList)
        {
            IBaseList <EdmMember> structuralMembers = TypeHelpers.GetAllStructuralMembers(edmType);

            ColumnMap[] columnMapArray = new ColumnMap[structuralMembers.Count];
            int         index          = 0;

            foreach (EdmMember member in (IEnumerable)structuralMembers)
            {
                if (!Helper.IsScalarType(member.TypeUsage.EdmType))
                {
                    throw new InvalidOperationException(Strings.ADP_InvalidDataReaderUnableToMaterializeNonScalarType((object)member.Name, (object)member.TypeUsage.EdmType.FullName));
                }
                int ordinalFromReader = ColumnMapFactory.GetMemberOrdinalFromReader(storeDataReader, member, edmType, renameList);
                columnMapArray[index] = (ColumnMap) new ScalarColumnMap(member.TypeUsage, member.Name, 0, ordinalFromReader);
                ++index;
            }
            return(columnMapArray);
        }
Пример #15
0
 private ColumnMap Copy(ColumnMap columnMap)
 {
     return(ColumnMapCopier.Copy(columnMap, m_varMap));
 }
Пример #16
0
        internal virtual CollectionColumnMap CreateColumnMapFromReaderAndClrType(
            DbDataReader reader, Type type, MetadataWorkspace workspace)
        {
            DebugCheck.NotNull(reader);
            DebugCheck.NotNull(type);
            DebugCheck.NotNull(workspace);

            // we require a default constructor
            var constructor = type.GetDeclaredConstructor();

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

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

            foreach (var prop in type.GetInstanceProperties()
                     .Select(p => p.GetPropertyInfoForSet()))
            {
                // for enums unwrap the type if nullable
                var propertyUnderlyingType = Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType;
                var propType = propertyUnderlyingType.IsEnum() ? propertyUnderlyingType.GetEnumUnderlyingType() : prop.PropertyType;

                EdmType modelType;
                int     ordinal;

                if (TryGetColumnOrdinalFromReader(reader, prop.Name, out ordinal) &&
                    workspace.TryDetermineCSpaceModelType(propType, out modelType) &&
                    (Helper.IsScalarType(modelType)) &&
                    prop.CanWriteExtended() &&
                    prop.GetIndexParameters().Length == 0 &&
                    null != prop.Setter())
                {
                    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
            var members         = new MemberInfo[memberInfo.Count];
            var memberBindings  = new MemberBinding[memberInfo.Count];
            var propertyMaps    = new ColumnMap[memberInfo.Count];
            var modelProperties = new EdmProperty[memberInfo.Count];
            var 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 new InvalidOperationException(
                              Strings.ObjectContext_TwoPropertiesMappedToSameColumn(
                                  reader.GetName(memberGroup.Key),
                                  String.Join(", ", memberGroup.Select(tuple => tuple.Item3.Name).ToArray())));
                }

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

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

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

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

            return(collectionMap);
        }