protected override Expression VisitStructureExpression(StructureExpression expression) { var tupleExpression = GetTupleExpression(expression); var typeInfo = expression.PersistentType; var tuplePrototype = typeInfo.TuplePrototype; var mappingInfo = expression.Fields .OfType <FieldExpression>() .Where(f => f.ExtendedType == ExtendedExpressionType.Field) .OrderBy(f => f.Field.MappingInfo.Offset) .Select(f => new Pair <int>(f.Field.MappingInfo.Offset, f.Mapping.Offset)) .Distinct() .ToArray(); int[] columnMap = MaterializationHelper.CreateSingleSourceMap(tuplePrototype.Count, mappingInfo); var persistentTupleExpression = (Expression)Expression.Call( BuildPersistentTupleMethod, tupleExpression, Expression.Constant(tuplePrototype), Expression.Constant(columnMap)); return(Expression.Convert( Expression.Call( WellKnownMembers.CreateStructure, Expression.Field(itemMaterializationContextParameter, ItemMaterializationContext.SessionFieldInfo), Expression.Constant(expression.Type), persistentTupleExpression), expression.Type)); }
public TypeMapping GetTypeMapping(int entityIndex, TypeInfo approximateType, int typeId, Pair <int>[] columns) { TypeMapping result; var cache = entityMappings[entityIndex]; if (cache.SingleItem != null) { if (typeId != ResolveTypeToNodeSpecificTypeIdentifier(cache.SingleItem.Type)) { throw new ArgumentOutOfRangeException("typeId"); } return(cache.SingleItem); } if (cache.Items.TryGetValue(typeId, out result)) { return(result); } var type = TypeIdRegistry[typeId]; var keyInfo = type.Key; var descriptor = type.TupleDescriptor; var typeColumnMap = columns.ToArray(); if (approximateType.IsInterface) { // fixup target index for (int i = 0; i < columns.Length; i++) { var pair = typeColumnMap[i]; var approxTargetIndex = pair.First; var interfaceField = approximateType.Columns[approxTargetIndex].Field; var field = type.FieldMap[interfaceField]; var targetIndex = field.MappingInfo.Offset; typeColumnMap[i] = new Pair <int>(targetIndex, pair.Second); } } int[] allIndexes = MaterializationHelper.CreateSingleSourceMap(descriptor.Count, typeColumnMap); int[] keyIndexes = allIndexes.Take(keyInfo.TupleDescriptor.Count).ToArray(); var transform = new MapTransform(true, descriptor, allIndexes); var keyTransform = new MapTransform(true, keyInfo.TupleDescriptor, keyIndexes); result = new TypeMapping(type, keyTransform, transform, keyIndexes); if (type.Hierarchy.Root.IsLeaf && approximateType == type) { cache.SingleItem = result; } else { cache.Items.Add(typeId, result); } entityMappings[entityIndex] = cache; return(result); }