/// <summary> /// SimpleCollectionColumnMap /// </summary> internal override void Visit(SimpleCollectionColumnMap columnMap, Dump dumper) { using (new AutoXml(dumper, "SimpleCollection", GetAttributes(columnMap))) { DumpCollection(columnMap, dumper); } }
/// <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() { DebugCheck.NotNull(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) { var newElementColumnMap = columnMap.Element.Accept(this, replacementVarMap); var newKeys = VisitList(columnMap.Keys, replacementVarMap); var newForeignKeys = VisitList(columnMap.ForeignKeys, replacementVarMap); return(new SimpleCollectionColumnMap(columnMap.Type, columnMap.Name, newElementColumnMap, newKeys, newForeignKeys)); }
// <summary> // Creates a column map for the given reader and function mapping. // </summary> internal virtual CollectionColumnMap CreateFunctionImportStructuralTypeColumnMap( DbDataReader storeDataReader, FunctionImportMappingNonComposable mapping, int resultSetIndex, EntitySet entitySet, StructuralType baseStructuralType) { var 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 var baseEntityType = baseStructuralType as EntityType; Debug.Assert(null != baseEntityType, "We should have entity type here"); // Generate column maps for all discriminators var 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 var typeChoices = new Dictionary <EntityType, TypedColumnMap>(mappedEntityTypes.Count); ColumnMap[] baseTypeColumnMaps = null; foreach (var entityType in mappedEntityTypes) { var propertyColumnMaps = GetColumnMapsForType(storeDataReader, entityType, resultMapping.ReturnTypeColumnsRenameMapping); var 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. var 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); }
internal virtual PhysicalProjectOp CreatePhysicalProjectOp(Var outputVar) { VarList varList = Command.CreateVarList(); varList.Add(outputVar); VarRefColumnMap varRefColumnMap = new VarRefColumnMap(outputVar); SimpleCollectionColumnMap columnMap = new SimpleCollectionColumnMap(TypeUtils.CreateCollectionType(varRefColumnMap.Type), (string)null, (ColumnMap)varRefColumnMap, new SimpleColumnMap[0], new SimpleColumnMap[0]); return(this.CreatePhysicalProjectOp(varList, columnMap)); }
internal override ColumnMap Visit( SimpleCollectionColumnMap columnMap, VarMap replacementVarMap) { ColumnMap elementMap = columnMap.Element.Accept <ColumnMap, VarMap>((ColumnMapVisitorWithResults <ColumnMap, VarMap>) this, replacementVarMap); SimpleColumnMap[] keys = this.VisitList <SimpleColumnMap>(columnMap.Keys, replacementVarMap); SimpleColumnMap[] foreignKeys = this.VisitList <SimpleColumnMap>(columnMap.ForeignKeys, replacementVarMap); return((ColumnMap) new SimpleCollectionColumnMap(columnMap.Type, columnMap.Name, elementMap, keys, foreignKeys)); }
// <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); }
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); }
internal override void Visit(SimpleCollectionColumnMap columnMap, Dump dumper) { using (new Dump.AutoXml(dumper, "SimpleCollection", Dump.ColumnMapDumper.GetAttributes((ColumnMap)columnMap))) this.DumpCollection((CollectionColumnMap)columnMap, dumper); }
internal virtual PhysicalProjectOp CreatePhysicalProjectOp( VarList outputVars, SimpleCollectionColumnMap columnMap) { return(new PhysicalProjectOp(outputVars, columnMap)); }
internal PhysicalProjectOp(VarList outputVars, SimpleCollectionColumnMap columnMap) : this() { this.m_outputVars = outputVars; this.m_columnMap = columnMap; }