/// <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)); }
// <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]; }
private static Dictionary <string, object> GetAttributes(ColumnMap columnMap) { return(new Dictionary <string, object>() { { "Type", (object)columnMap.Type.ToString() } }); }
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)); }
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; }
/// <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; }
// <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); }
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())); }
// <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); }
private ColumnMap Copy(ColumnMap columnMap) { return(ColumnMapCopier.Copy(columnMap, m_varMap)); }
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); }