private void BuildConverter() { var itemType = isKeyConverter ? entityTypestoredInKey : typeof(TItem); var index = 0; var types = new TupleTypeCollection(); if (IsPersistableType(itemType)) { Expression = (Expression)BuildField(itemType, ref index, types); TupleDescriptor = TupleDescriptor.Create(types.ToArray(types.Count)); } else { var processedTypes = new HashSet <Type>(); var itemExpression = BuildLocalCollectionExpression(itemType, processedTypes, ref index, null, types); TupleDescriptor = TupleDescriptor.Create(types.ToArray(types.Count)); Expression = itemExpression; } converter = delegate(TItem item) { Tuple tuple = Tuple.Create(TupleDescriptor); if (ReferenceEquals(item, null)) { return(tuple); } FillLocalCollectionField(item, tuple, Expression); return(tuple); }; }
private IMappedExpression BuildField(Type type, ref int index, TupleTypeCollection types) { // if (type.IsOfGenericType(typeof (Ref<>))) { // var entityType = type.GetGenericType(typeof (Ref<>)).GetGenericArguments()[0]; // TypeInfo typeInfo = model.Types[entityType]; // KeyInfo keyProviderInfo = typeInfo.KeyInfo; // TupleDescriptor keyTupleDescriptor = keyProviderInfo.TupleDescriptor; // KeyExpression entityExpression = KeyExpression.Create(typeInfo, index); // index += keyTupleDescriptor.Count; // types = types.Concat(keyTupleDescriptor); // return Expression.Convert(entityExpression, type); // } if (type.IsSubclassOf(typeof(Entity))) { TypeInfo typeInfo = model.Types[type]; KeyInfo keyInfo = typeInfo.Key; TupleDescriptor keyTupleDescriptor = keyInfo.TupleDescriptor; IMappedExpression expression; if (isKeyConverter) { expression = KeyExpression.Create(typeInfo, index); } else { var entityExpression = EntityExpression.Create(typeInfo, index, true); entityExpression.IsNullable = true; expression = entityExpression; } index += keyTupleDescriptor.Count; types.AddRange(keyTupleDescriptor); return(expression); } if (type.IsSubclassOf(typeof(Structure))) { TypeInfo typeInfo = model.Types[type]; TupleDescriptor tupleDescriptor = typeInfo.TupleDescriptor; var tupleSegment = new Segment <int>(index, tupleDescriptor.Count); StructureExpression structureExpression = StructureExpression.CreateLocalCollectionStructure(typeInfo, tupleSegment); index += tupleDescriptor.Count; types.AddRange(tupleDescriptor); return(structureExpression); } if (TypeIsStorageMappable(type)) { ColumnExpression columnExpression = ColumnExpression.Create(type, index); types.Add(type); index++; return(columnExpression); } throw new NotSupportedException(); }
private LocalCollectionExpression BuildLocalCollectionExpression(Type type, HashSet <Type> processedTypes, ref int columnIndex, MemberInfo parentMember, TupleTypeCollection types) { if (type.IsAssignableFrom(typeof(Key))) { throw new InvalidOperationException(String.Format(Strings.ExUnableToStoreUntypedKeyToStorage, typeof(Ref <>).GetShortName())); } if (!processedTypes.Add(type)) { throw new InvalidOperationException(String.Format(Strings.ExUnableToPersistTypeXBecauseOfLoopReference, type.FullName)); } IEnumerable <MemberInfo> members = type .GetProperties(BindingFlags.Instance | BindingFlags.Public) .Where(propertyInfo => propertyInfo.CanRead) .Cast <MemberInfo>() .Concat(type.GetFields(BindingFlags.Instance | BindingFlags.Public)); var fields = new Dictionary <MemberInfo, IMappedExpression>(); foreach (MemberInfo memberInfo in members) { var propertyInfo = memberInfo as PropertyInfo; Type memberType = propertyInfo == null ? ((FieldInfo)memberInfo).FieldType : propertyInfo.PropertyType; if (IsPersistableType(memberType)) { IMappedExpression expression = BuildField(memberType, ref columnIndex, types); fields.Add(memberInfo, expression); } else { LocalCollectionExpression collectionExpression = BuildLocalCollectionExpression(memberType, new HashSet <Type>(processedTypes), ref columnIndex, memberInfo, types); fields.Add(memberInfo, collectionExpression); } } if (fields.Count == 0) { throw new InvalidOperationException(String.Format(Strings.ExTypeXDoesNotHasAnyPublicReadablePropertiesOrFieldsSoItCanTBePersistedToStorage, type.FullName)); } var result = new LocalCollectionExpression(type, parentMember, sourceExpression); result.Fields = fields; return(result); }