internal virtual CollectionColumnMap CreateColumnMapFromReaderAndType(
            DbDataReader storeDataReader,
            EdmType edmType,
            EntitySet entitySet,
            Dictionary <string, FunctionImportReturnTypeStructuralTypeColumnRenameMapping> renameList)
        {
            ColumnMap[] columnMapsForType = ColumnMapFactory.GetColumnMapsForType(storeDataReader, edmType, renameList);
            ColumnMap   elementMap        = (ColumnMap)null;

            if (Helper.IsRowType((GlobalItem)edmType))
            {
                elementMap = (ColumnMap) new RecordColumnMap(TypeUsage.Create(edmType), edmType.Name, columnMapsForType, (SimpleColumnMap)null);
            }
            else if (Helper.IsComplexType(edmType))
            {
                elementMap = (ColumnMap) new ComplexTypeColumnMap(TypeUsage.Create(edmType), edmType.Name, columnMapsForType, (SimpleColumnMap)null);
            }
            else if (Helper.IsScalarType(edmType))
            {
                if (storeDataReader.FieldCount != 1)
                {
                    throw new EntityCommandExecutionException(Strings.ADP_InvalidDataReaderFieldCountForScalarType);
                }
                elementMap = (ColumnMap) new ScalarColumnMap(TypeUsage.Create(edmType), edmType.Name, 0, 0);
            }
            else if (Helper.IsEntityType(edmType))
            {
                elementMap = (ColumnMap)ColumnMapFactory.CreateEntityTypeElementColumnMap(storeDataReader, edmType, entitySet, columnMapsForType, (Dictionary <string, FunctionImportReturnTypeStructuralTypeColumnRenameMapping>)null);
            }
            return((CollectionColumnMap) new SimpleCollectionColumnMap(edmType.GetCollectionType().TypeUsage, edmType.Name, elementMap, (SimpleColumnMap[])null, (SimpleColumnMap[])null));
        }
        private static EntityColumnMap CreateEntityTypeElementColumnMap(
            DbDataReader storeDataReader,
            EdmType edmType,
            EntitySet entitySet,
            ColumnMap[] propertyColumnMaps,
            Dictionary <string, FunctionImportReturnTypeStructuralTypeColumnRenameMapping> renameList)
        {
            EntityType entityType = (EntityType)edmType;

            ColumnMap[] columnMapArray = new ColumnMap[storeDataReader.FieldCount];
            foreach (ColumnMap propertyColumnMap in propertyColumnMaps)
            {
                int columnPos = ((ScalarColumnMap)propertyColumnMap).ColumnPos;
                columnMapArray[columnPos] = propertyColumnMap;
            }
            IList <EdmMember> keyMembers = (IList <EdmMember>)entityType.KeyMembers;

            SimpleColumnMap[] keyColumns = new SimpleColumnMap[keyMembers.Count];
            int index = 0;

            foreach (EdmMember member in (IEnumerable <EdmMember>)keyMembers)
            {
                int       ordinalFromReader = ColumnMapFactory.GetMemberOrdinalFromReader(storeDataReader, member, edmType, renameList);
                ColumnMap columnMap         = columnMapArray[ordinalFromReader];
                keyColumns[index] = (SimpleColumnMap)columnMap;
                ++index;
            }
            SimpleEntityIdentity simpleEntityIdentity = new SimpleEntityIdentity(entitySet, keyColumns);

            return(new EntityColumnMap(TypeUsage.Create(edmType), edmType.Name, propertyColumnMaps, (EntityIdentity)simpleEntityIdentity));
        }
        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));
        }
        private static int GetDiscriminatorOrdinalFromReader(
            DbDataReader storeDataReader,
            string columnName,
            EdmFunction functionImport)
        {
            int ordinal;

            if (!ColumnMapFactory.TryGetColumnOrdinalFromReader(storeDataReader, columnName, out ordinal))
            {
                throw new EntityCommandExecutionException(Strings.ADP_InvalidDataReaderMissingDiscriminatorColumn((object)columnName, (object)functionImport.FullName));
            }
            return(ordinal);
        }
        private static int GetMemberOrdinalFromReader(
            DbDataReader storeDataReader,
            EdmMember member,
            EdmType currentType,
            Dictionary <string, FunctionImportReturnTypeStructuralTypeColumnRenameMapping> renameList)
        {
            string renameForMember = ColumnMapFactory.GetRenameForMember(member, currentType, renameList);
            int    ordinal;

            if (!ColumnMapFactory.TryGetColumnOrdinalFromReader(storeDataReader, renameForMember, out ordinal))
            {
                throw new EntityCommandExecutionException(Strings.ADP_InvalidDataReaderMissingColumnForType((object)currentType.FullName, (object)member.Name));
            }
            return(ordinal);
        }
        private static ScalarColumnMap[] CreateDiscriminatorColumnMaps(
            DbDataReader storeDataReader,
            FunctionImportMappingNonComposable mapping,
            int resultIndex)
        {
            TypeUsage      type = TypeUsage.Create((EdmType)MetadataItem.EdmProviderManifest.GetPrimitiveType(PrimitiveTypeKind.String));
            IList <string> discriminatorColumns = mapping.GetDiscriminatorColumns(resultIndex);

            ScalarColumnMap[] scalarColumnMapArray = new ScalarColumnMap[discriminatorColumns.Count];
            for (int index = 0; index < scalarColumnMapArray.Length; ++index)
            {
                string          str             = discriminatorColumns[index];
                ScalarColumnMap scalarColumnMap = new ScalarColumnMap(type, str, 0, ColumnMapFactory.GetDiscriminatorOrdinalFromReader(storeDataReader, str, mapping.FunctionImport));
                scalarColumnMapArray[index] = scalarColumnMap;
            }
            return(scalarColumnMapArray);
        }
        internal virtual CollectionColumnMap CreateFunctionImportStructuralTypeColumnMap(
            DbDataReader storeDataReader,
            FunctionImportMappingNonComposable mapping,
            int resultSetIndex,
            EntitySet entitySet,
            StructuralType baseStructuralType)
        {
            FunctionImportStructuralTypeMappingKB resultMapping = mapping.GetResultMapping(resultSetIndex);

            if (resultMapping.NormalizedEntityTypeMappings.Count == 0)
            {
                return(this.CreateColumnMapFromReaderAndType(storeDataReader, (EdmType)baseStructuralType, entitySet, resultMapping.ReturnTypeColumnsRenameMapping));
            }
            EntityType entityType = baseStructuralType as EntityType;

            ScalarColumnMap[]    discriminatorColumnMaps = ColumnMapFactory.CreateDiscriminatorColumnMaps(storeDataReader, mapping, resultSetIndex);
            HashSet <EntityType> entityTypeSet           = new HashSet <EntityType>((IEnumerable <EntityType>)resultMapping.MappedEntityTypes);

            entityTypeSet.Add(entityType);
            Dictionary <EntityType, TypedColumnMap> typeChoices = new Dictionary <EntityType, TypedColumnMap>(entityTypeSet.Count);

            ColumnMap[] baseTypeColumns = (ColumnMap[])null;
            foreach (EntityType key in entityTypeSet)
            {
                ColumnMap[]     columnMapsForType = ColumnMapFactory.GetColumnMapsForType(storeDataReader, (EdmType)key, resultMapping.ReturnTypeColumnsRenameMapping);
                EntityColumnMap elementColumnMap  = ColumnMapFactory.CreateEntityTypeElementColumnMap(storeDataReader, (EdmType)key, entitySet, columnMapsForType, resultMapping.ReturnTypeColumnsRenameMapping);
                if (!key.Abstract)
                {
                    typeChoices.Add(key, (TypedColumnMap)elementColumnMap);
                }
                if (key == baseStructuralType)
                {
                    baseTypeColumns = columnMapsForType;
                }
            }
            MultipleDiscriminatorPolymorphicColumnMap polymorphicColumnMap = new MultipleDiscriminatorPolymorphicColumnMap(TypeUsage.Create((EdmType)baseStructuralType), baseStructuralType.Name, baseTypeColumns, (SimpleColumnMap[])discriminatorColumnMaps, typeChoices, (Func <object[], EntityType>)(discriminatorValues => mapping.Discriminate(discriminatorValues, resultSetIndex)));

            return((CollectionColumnMap) new SimpleCollectionColumnMap(baseStructuralType.GetCollectionType().TypeUsage, baseStructuralType.Name, (ColumnMap)polymorphicColumnMap, (SimpleColumnMap[])null, (SimpleColumnMap[])null));
        }
        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);
        }
Example #9
0
        private static ObjectContext CreateObjectContext(
            Mock<EntityConnection> entityConnectionMock = null, Mock<ObjectStateManager> objectStateManagerMock = null,
            Mock<MetadataWorkspace> metadataWorkspaceMock = null, ObjectQueryExecutionPlanFactory objectQueryExecutionPlanFactory = null,
            Translator translator = null, ColumnMapFactory columnMapFactory = null, DbCommand dbCommand = null)
        {
            if (objectStateManagerMock == null)
            {
                objectStateManagerMock = new Mock<ObjectStateManager>();
            }

            if (metadataWorkspaceMock == null)
            {
                metadataWorkspaceMock = new Mock<MetadataWorkspace>();
                metadataWorkspaceMock.Setup(m => m.IsItemCollectionAlreadyRegistered(DataSpace.OSpace)).Returns(true);
                metadataWorkspaceMock.Setup(m => m.GetItemCollection(DataSpace.OCSpace)).Returns(default(ItemCollection));
                metadataWorkspaceMock.Setup(m => m.IsItemCollectionAlreadyRegistered(DataSpace.SSpace)).Returns(true);

                var storeItemCollection = new StoreItemCollection(
                    GenericProviderFactory<DbProviderFactory>.Instance, new SqlProviderManifest("2008"), "System.Data.FakeSqlClient", "2008");
                metadataWorkspaceMock.Setup(m => m.GetItemCollection(DataSpace.SSpace)).Returns(storeItemCollection);
            }

            if (entityConnectionMock == null)
            {
                var dbConnectionMock = new Mock<DbConnection>();
                if (dbCommand != null)
                {
                    dbConnectionMock.Protected().Setup<DbCommand>("CreateDbCommand").Returns(() => dbCommand);
                }
                dbConnectionMock.Setup(m => m.DataSource).Returns("fakeDb");

                entityConnectionMock = new Mock<EntityConnection>();
                entityConnectionMock.SetupGet(m => m.ConnectionString).Returns("BarConnection");
                entityConnectionMock.SetupGet(m => m.State).Returns(() => ConnectionState.Open);
                entityConnectionMock.SetupGet(m => m.StoreConnection).Returns(dbConnectionMock.Object);
                entityConnectionMock.Setup(m => m.GetMetadataWorkspace()).Returns(metadataWorkspaceMock.Object);
            }

            var objectContextMock = new Mock<ObjectContext>(objectQueryExecutionPlanFactory, translator, columnMapFactory, null)
                {
                    CallBase = true
                };

            objectContextMock.Setup(m => m.Connection).Returns(entityConnectionMock.Object);
            objectContextMock.Setup(m => m.ObjectStateManager).Returns(() => objectStateManagerMock.Object);
            objectContextMock.Setup(m => m.MetadataWorkspace).Returns(() => metadataWorkspaceMock.Object);
            objectContextMock.Setup(m => m.DefaultContainerName).Returns("Bar");

            return objectContextMock.Object;
        }
 internal FunctionColumnMapGenerator(
     FunctionImportMappingNonComposable mapping,
     int resultSetIndex,
     EntitySet entitySet,
     StructuralType baseStructuralType,
     ColumnMapFactory columnMapFactory)
 {
     _mapping = mapping;
     _entitySet = entitySet;
     _baseStructuralType = baseStructuralType;
     _resultSetIndex = resultSetIndex;
     _columnMapFactory = columnMapFactory;
 }
        internal EntityCommandDefinition(
            DbProviderFactory storeProviderFactory,
            DbCommandTree commandTree, 
            DbInterceptionContext interceptionContext,
            IDbDependencyResolver resolver = null,
            BridgeDataReaderFactory bridgeDataReaderFactory = null,
            ColumnMapFactory columnMapFactory = null)
        {
            DebugCheck.NotNull(storeProviderFactory);
            DebugCheck.NotNull(commandTree);
            DebugCheck.NotNull(interceptionContext);

            _bridgeDataReaderFactory = bridgeDataReaderFactory ?? new BridgeDataReaderFactory();
            _columnMapFactory = columnMapFactory ?? new ColumnMapFactory();

            _storeProviderServices =
                (resolver != null
                     ? resolver.GetService<DbProviderServices>(storeProviderFactory.GetProviderInvariantName())
                     : null) ??
                storeProviderFactory.GetProviderServices();

            try
            {
                if (DbCommandTreeKind.Query
                    == commandTree.CommandTreeKind)
                {
                    // Next compile the plan for the command tree
                    var mappedCommandList = new List<ProviderCommandInfo>();
                    ColumnMap columnMap;
                    int columnCount;
                    PlanCompiler.Compile(commandTree, out mappedCommandList, out columnMap, out columnCount, out _entitySets);
                    _columnMapGenerators = new IColumnMapGenerator[] { new ConstantColumnMapGenerator(columnMap, columnCount) };
                    // Note: we presume that the first item in the ProviderCommandInfo is the root node;
                    Debug.Assert(mappedCommandList.Count > 0, "empty providerCommandInfo collection and no exception?");
                    // this shouldn't ever happen.

                    // Then, generate the store commands from the resulting command tree(s)
                    _mappedCommandDefinitions = new List<DbCommandDefinition>(mappedCommandList.Count);

                    foreach (var providerCommandInfo in mappedCommandList)
                    {
                        var providerCommandDefinition = _storeProviderServices.CreateCommandDefinition(
                            providerCommandInfo.CommandTree, interceptionContext);

                        if (null == providerCommandDefinition)
                        {
                            throw new ProviderIncompatibleException(Strings.ProviderReturnedNullForCreateCommandDefinition);
                        }

                        _mappedCommandDefinitions.Add(providerCommandDefinition);
                    }
                }
                else
                {
                    Debug.Assert(
                        DbCommandTreeKind.Function == commandTree.CommandTreeKind, "only query and function command trees are supported");
                    var entityCommandTree = (DbFunctionCommandTree)commandTree;

                    // Retrieve mapping and metadata information for the function import.
                    var mapping = GetTargetFunctionMapping(entityCommandTree);
                    IList<FunctionParameter> returnParameters = entityCommandTree.EdmFunction.ReturnParameters;
                    var resultSetCount = returnParameters.Count > 1 ? returnParameters.Count : 1;
                    _columnMapGenerators = new IColumnMapGenerator[resultSetCount];
                    var storeResultType = DetermineStoreResultType(mapping, 0, out _columnMapGenerators[0]);
                    for (var i = 1; i < resultSetCount; i++)
                    {
                        DetermineStoreResultType(mapping, i, out _columnMapGenerators[i]);
                    }

                    // Copy over parameters (this happens through a more indirect route in the plan compiler, but
                    // it happens nonetheless)
                    var providerParameters = new List<KeyValuePair<string, TypeUsage>>();
                    foreach (var parameter in entityCommandTree.Parameters)
                    {
                        providerParameters.Add(parameter);
                    }

                    // Construct store command tree usage.
                    var providerCommandTree = new DbFunctionCommandTree(
                        entityCommandTree.MetadataWorkspace, DataSpace.SSpace,
                        mapping.TargetFunction, storeResultType, providerParameters);

                    var storeCommandDefinition = _storeProviderServices.CreateCommandDefinition(providerCommandTree);
                    _mappedCommandDefinitions = new List<DbCommandDefinition>(1)
                        {
                            storeCommandDefinition
                        };

                    var firstResultEntitySet = mapping.FunctionImport.EntitySets.FirstOrDefault();
                    if (firstResultEntitySet != null)
                    {
                        _entitySets = new Set<EntitySet>();
                        _entitySets.Add(mapping.FunctionImport.EntitySets.FirstOrDefault());
                        _entitySets.MakeReadOnly();
                    }
                }

                // Finally, build a list of the parameters that the resulting command should have;
                var parameterList = new List<EntityParameter>();

                foreach (var queryParameter in commandTree.Parameters)
                {
                    var parameter = CreateEntityParameterFromQueryParameter(queryParameter);
                    parameterList.Add(parameter);
                }

                _parameters = new ReadOnlyCollection<EntityParameter>(parameterList);
            }
            catch (EntityCommandCompilationException)
            {
                // No need to re-wrap EntityCommandCompilationException
                throw;
            }
            catch (Exception e)
            {
                // we should not be wrapping all exceptions
                if (e.IsCatchableExceptionType())
                {
                    // we don't wan't folks to have to know all the various types of exceptions that can 
                    // occur, so we just rethrow a CommandDefinitionException and make whatever we caught  
                    // the inner exception of it.
                    throw new EntityCommandCompilationException(Strings.EntityClient_CommandDefinitionPreparationFailed, e);
                }

                throw;
            }
        }
 /// <summary>
 ///     Constructor for testing/mocking purposes.
 /// </summary>
 protected EntityCommandDefinition(
     BridgeDataReaderFactory factory = null,
     ColumnMapFactory columnMapFactory = null,
     List<DbCommandDefinition> mappedCommandDefinitions = null)
 {
     _bridgeDataReaderFactory = factory ?? new BridgeDataReaderFactory();
     _columnMapFactory = columnMapFactory ?? new ColumnMapFactory();
     _mappedCommandDefinitions = mappedCommandDefinitions;
 }