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); }
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; }