public IEnumerable <Record> Read(IEnumerable <Tuple> source, RecordSetHeader header, Session session) { CacheItem cacheItem; var recordPartCount = header.ColumnGroups.Count; var context = new MaterializationContext(session, recordPartCount); lock (_lock) { if (!cache.TryGetItem(header, false, out cacheItem)) { var typeIdColumnName = Domain.Handlers.NameBuilder.TypeIdColumnName; var model = context.Model; var mappings = new RecordPartMapping[recordPartCount]; for (int i = 0; i < recordPartCount; i++) { var columnGroup = header.ColumnGroups[i]; var approximateType = columnGroup.TypeInfoRef.Resolve(model); var columnMapping = new List <Pair <int> >(); var typeIdColumnIndex = -1; foreach (var columnIndex in columnGroup.Columns) { var column = (MappedColumn)header.Columns[columnIndex]; var columnInfo = column.ColumnInfoRef.Resolve(model); FieldInfo fieldInfo; if (!approximateType.Fields.TryGetValue(columnInfo.Field.Name, out fieldInfo)) { continue; } var targetColumnIndex = fieldInfo.MappingInfo.Offset; if (columnInfo.Name == typeIdColumnName) { typeIdColumnIndex = column.Index; } columnMapping.Add(new Pair <int>(targetColumnIndex, columnIndex)); } mappings[i] = new RecordPartMapping(typeIdColumnIndex, columnMapping.ToArray(), approximateType); } cacheItem = new CacheItem(header, mappings); cache.Add(cacheItem); } } return(source.Select(tuple => ParseRow(tuple, context, cacheItem.Mappings))); }
private Pair <Key, Tuple> ParseColumnGroup(Tuple tuple, MaterializationContext context, int groupIndex, RecordPartMapping mapping) { TypeReferenceAccuracy accuracy; int typeId = ExtractTypeId(mapping.ApproximateType, context.TypeIdRegistry, tuple, mapping.TypeIdColumnIndex, out accuracy); var typeMapping = typeId == TypeInfo.NoTypeId ? null : context.GetTypeMapping(groupIndex, mapping.ApproximateType, typeId, mapping.Columns); if (typeMapping == null) { return(new Pair <Key, Tuple>(null, null)); } bool canCache = accuracy == TypeReferenceAccuracy.ExactType; Key key; if (typeMapping.KeyTransform.Descriptor.Count <= WellKnown.MaxGenericKeyLength) { key = KeyFactory.Materialize(Domain, context.Session.StorageNodeId, typeMapping.Type, tuple, accuracy, canCache, typeMapping.KeyIndexes); } else { var keyTuple = typeMapping.KeyTransform.Apply(TupleTransformType.TransformedTuple, tuple); key = KeyFactory.Materialize(Domain, context.Session.StorageNodeId, typeMapping.Type, keyTuple, accuracy, canCache, null); } if (accuracy == TypeReferenceAccuracy.ExactType) { var entityTuple = typeMapping.Transform.Apply(TupleTransformType.Tuple, tuple); return(new Pair <Key, Tuple>(key, entityTuple)); } return(new Pair <Key, Tuple>(key, null)); }