private ComplexTypeMaterializer.Plan GetPlan(DataRecordInfo recordInfo) { ComplexTypeMaterializer.Plan[] planArray = this._lastPlans ?? (this._lastPlans = new ComplexTypeMaterializer.Plan[4]); int index1 = this._lastPlanIndex - 1; for (int index2 = 0; index2 < 4; ++index2) { index1 = (index1 + 1) % 4; if (planArray[index1] != null) { if (planArray[index1].Key == recordInfo.RecordType) { this._lastPlanIndex = index1; return(planArray[index1]); } } else { break; } } ObjectTypeMapping objectMapping = Util.GetObjectMapping(recordInfo.RecordType.EdmType, this._workspace); this._lastPlanIndex = index1; planArray[index1] = new ComplexTypeMaterializer.Plan(recordInfo.RecordType, objectMapping, recordInfo.FieldMetadata); return(planArray[index1]); }
internal StateManagerTypeMetadata(EdmType edmType, ObjectTypeMapping mapping) { this._typeUsage = TypeUsage.Create(edmType); this._recordInfo = new DataRecordInfo(this._typeUsage); ReadOnlyMetadataCollection <EdmProperty> properties = TypeHelpers.GetProperties(edmType); this._members = new StateManagerMemberMetadata[properties.Count]; this._objectNameToOrdinal = new Dictionary <string, int>(properties.Count); this._cLayerNameToOrdinal = new Dictionary <string, int>(properties.Count); ReadOnlyMetadataCollection <EdmMember> metadataCollection = (ReadOnlyMetadataCollection <EdmMember>)null; if (Helper.IsEntityType(edmType)) { metadataCollection = ((EntityTypeBase)edmType).KeyMembers; } for (int index = 0; index < this._members.Length; ++index) { EdmProperty memberMetadata = properties[index]; ObjectPropertyMapping memberMap = (ObjectPropertyMapping)null; if (mapping != null) { memberMap = mapping.GetPropertyMap(memberMetadata.Name); if (memberMap != null) { this._objectNameToOrdinal.Add(memberMap.ClrProperty.Name, index); } } this._cLayerNameToOrdinal.Add(memberMetadata.Name, index); this._members[index] = new StateManagerMemberMetadata(memberMap, memberMetadata, metadataCollection != null && metadataCollection.Contains((EdmMember)memberMetadata)); } }
private bool InitializeTypeMappings() { foreach (var module in _server.Modules) { var mname = module.GetType().Name; foreach (var entMapping in module.EntityMappings) { var typeDef = _model.GetTypeDef(entMapping.GraphQLType); if (typeDef == null) { AddError($"Mapping target type {entMapping.GraphQLType.Name} is not registered; module {mname}"); continue; } if (!(typeDef is ObjectTypeDef objTypeDef)) { AddError($"Invalid mapping target type {entMapping.GraphQLType.Name}, must be Object type; module {mname}"); continue; } var typeMapping = new ObjectTypeMapping(objTypeDef, entMapping.EntityType, entMapping.Expression); RegisterTypeMapping(typeMapping); } // foreach mapping } // Add self-maps to all objects, including module-level Query, Mutation types foreach (var typeDef in _model.Types) { if (typeDef is ObjectTypeDef otd) { var mappingExt = new ObjectTypeMapping(otd, otd.ClrType); otd.Mappings.Add(mappingExt); } } return(!_model.HasErrors); }
private void RegisterTypeMapping(ObjectTypeMapping mapping) { // register in ObjectTypeDef mapping.TypeDef.Mappings.Add(mapping); // register in global dict by entity type if (!_model.EntityMappings.TryGetValue(mapping.EntityType, out var mapList)) { mapList = new List <ObjectTypeMapping>(); _model.EntityMappings[mapping.EntityType] = mapList; } mapList.Add(mapping); }
private void AssignResolversByFieldResolverAttribute(ObjectTypeMapping mapping) { var typeDef = mapping.TypeDef; foreach (var field in typeDef.Fields) { if (field.ClrMember == null) { continue; //__typename has no clr member } var resAttr = GetAllAttributesAndAdjustments(field.ClrMember).Find <ResolverAttribute>(); if (resAttr == null) { continue; } var resolverType = resAttr.ResolverClass; if (resolverType != null) { if (!typeDef.Module.ResolverClasses.Contains(resolverType)) { AddError($"Field {typeDef.Name}.{field.Name}: target resolver class {resolverType.Name} is not registered with module. "); continue; } } // Get field res info and check if it's already mapped var methName = resAttr.MethodName ?? field.ClrMember.Name; var resMethInfos = FindResolvers(methName, resolverType); switch (resMethInfos.Count) { case 1: break; case 0: AddError($"Field {typeDef.Name}.{field.Name}: failed to find resolver method {methName}. "); continue; //next field default: AddError($"Field {typeDef.Name}.{field.Name}: found more than one resolver method ({methName})."); continue; //next field } // we have single matching resolver var resMethInfo = resMethInfos[0]; VerifyFieldResolverMethod(field, resMethInfo); // get field resolver info and check if it is already mapped var fldRes = mapping.GetResolver(field); if (fldRes.IsMapped()) { AddError($"Field {typeDef.Name}.{field.Name}: failed to set resolver '{methName}', field is already mapped. "); continue; //next field } fldRes.ResolverMethod = resMethInfo; } //foreach field } //method
private static Type GetDeclaringType(RelatedEnd relatedEnd) { if (relatedEnd.NavigationProperty != null) { EntityType declaringEntityType = (EntityType)relatedEnd.NavigationProperty.DeclaringType; ObjectTypeMapping mapping = System.Data.Common.Internal.Materialization.Util.GetObjectMapping(declaringEntityType, relatedEnd.WrappedOwner.Context.MetadataWorkspace); return(mapping.ClrType.ClrType); } else { return(relatedEnd.WrappedOwner.IdentityType); } }
private void VerifyAllResolversAssigned(ObjectTypeMapping mapping) { foreach (var fres in mapping.FieldResolvers) { // so far we have only exec type to set, or post error if (fres.ResolverFunc == null && fres.ResolverMethod == null) { var fldName = fres.Field.Name; var typeDef = mapping.TypeDef; var fldRef = $"'{typeDef.ClrType.Name}.{fldName}', mapping from (entity) type '{mapping.EntityType}', " + $" (module '{typeDef.Module.Name}')"; AddError($"Field '{fldName}' has no associated resolver or mapped entity field. Field: {fldRef}."); } } // foreach fres }
internal Plan( TypeUsage key, ObjectTypeMapping mapping, ReadOnlyCollection <FieldMetadata> fields) { this.Key = key; this.ClrType = DelegateFactory.GetConstructorDelegateForType((ClrComplexType)mapping.ClrType); this.Properties = new ComplexTypeMaterializer.PlanEdmProperty[fields.Count]; for (int index = 0; index < this.Properties.Length; ++index) { FieldMetadata field = fields[index]; int ordinal = field.Ordinal; this.Properties[index] = new ComplexTypeMaterializer.PlanEdmProperty(ordinal, mapping.GetPropertyMap(field.FieldType.Name).ClrProperty); } }
internal StateManagerTypeMetadata(EdmType edmType, ObjectTypeMapping mapping) { DebugCheck.NotNull(edmType); Debug.Assert( Helper.IsEntityType(edmType) || Helper.IsComplexType(edmType), "not Complex or EntityType"); Debug.Assert( ReferenceEquals(mapping, null) || ReferenceEquals(mapping.EdmType, edmType), "different EdmType instance"); _typeUsage = TypeUsage.Create(edmType); _recordInfo = new DataRecordInfo(_typeUsage); var members = TypeHelpers.GetProperties(edmType); _members = new StateManagerMemberMetadata[members.Count]; _objectNameToOrdinal = new Dictionary <string, int>(members.Count); _cLayerNameToOrdinal = new Dictionary <string, int>(members.Count); ReadOnlyMetadataCollection <EdmMember> keyMembers = null; if (Helper.IsEntityType(edmType)) { keyMembers = ((EntityType)edmType).KeyMembers; } for (var i = 0; i < _members.Length; ++i) { var member = members[i]; ObjectPropertyMapping memberMap = null; if (null != mapping) { memberMap = mapping.GetPropertyMap(member.Name); if (null != memberMap) { _objectNameToOrdinal.Add(memberMap.ClrProperty.Name, i); // olayer name } } _cLayerNameToOrdinal.Add(member.Name, i); // clayer name // Determine whether this member is part of the identity of the entity. _members[i] = new StateManagerMemberMetadata(memberMap, member, ((null != keyMembers) && keyMembers.Contains(member))); } }
} //method private void AssignResolversFromCompiledMappingExpressions(ObjectTypeMapping mapping) { if (mapping.Expression == null) { return; } var entityPrm = mapping.Expression.Parameters[0]; var memberInit = mapping.Expression.Body as MemberInitExpression; if (memberInit == null) { AddError($"Invalid mapping expression for type '{mapping.EntityType}->{mapping.TypeDef.Name}'."); return; } foreach (var bnd in memberInit.Bindings) { var asmtBnd = bnd as MemberAssignment; if (asmtBnd == null) { AddError($"Invalid mapping expression '{bnd}', expected assignment binding."); continue; } var fldName = bnd.Member.Name.FirstLower(); var fieldDef = mapping.TypeDef.Fields[fldName]; if (fieldDef == null) { AddError($"Invalid assignment expression, target field '{fldName}' not found."); continue; } // create lambda reading the source property var resInfo = mapping.GetResolver(fieldDef); if (resInfo == null) { continue; } if (resInfo.IsMapped()) { AddError($"Resolver mapper by LINQ expression: field '{fieldDef}' is already mapped to a resolver."); continue; } resInfo.ResolverFunc = CompileResolverExpression(entityPrm, asmtBnd.Expression); } //foreach bnd }
/// <summary> /// Given the type in the target space and the member name in the source space, /// get the corresponding member in the target space /// For e.g. consider a Conceptual Type Foo with a member bar and a CLR type /// XFoo with a member YBar. If one has a reference to Foo one can /// invoke GetMember(Foo,"YBar") to retrieve the member metadata for bar /// </summary> /// <param name="type">The type in the target perspective</param> /// <param name="memberName">the name of the member in the source perspective</param> /// <param name="ignoreCase">true for case-insensitive lookup</param> /// <param name="outMember">returns the edmMember if a match is found</param> /// <returns>true if a match is found, otherwise false</returns> internal override bool TryGetMember(StructuralType type, String memberName, bool ignoreCase, out EdmMember outMember) { outMember = null; Map map = null; if (this.MetadataWorkspace.TryGetMap(type, DataSpace.OCSpace, out map)) { ObjectTypeMapping objectTypeMap = map as ObjectTypeMapping; if (objectTypeMap != null) { ObjectMemberMapping objPropertyMapping = objectTypeMap.GetMemberMapForClrMember(memberName, ignoreCase); if (null != objPropertyMapping) { outMember = objPropertyMapping.EdmMember; return(true); } } } return(false); }
} //method // those members that do not have binding expressions, try mapping props with the same name private void AssignResolversByEntityPropertyNameMatch(ObjectTypeMapping mapping) { var entityType = mapping.EntityType; var allEntFldProps = entityType.GetFieldsProps(); foreach (var fldDef in mapping.TypeDef.Fields) { var res = mapping.GetResolver(fldDef); if (res.IsMapped()) { continue; //already set } var memberName = fldDef.Name; MemberInfo entMember = allEntFldProps.Where(m => m.Name.Equals(memberName, StringComparison.OrdinalIgnoreCase)) .FirstOrDefault(); if (entMember == null) { continue; } res.ResolverFunc = ExpressionHelper.CompileMemberReader(entMember); } //foreach fldDef }
private ObjectTypeDef BuildRootSchemaObject(string name, TypeRole typeRole, TypeRole moduleTypeRole) { var allModuleAggrTypes = _model.Types.OfType <ObjectTypeDef>() .Where(t => t.TypeRole == moduleTypeRole) .ToList(); if (allModuleAggrTypes.Count == 0) { return(null); } // create root object (ex: Query type) var rootObjTypeDef = new ObjectTypeDef(name, null, GraphQLModelObject.EmptyAttributeList, null, typeRole); RegisterTypeDef(rootObjTypeDef); var mapping = new ObjectTypeMapping(rootObjTypeDef, null); rootObjTypeDef.Mappings.Add(mapping); // copy resolvers foreach (var aggrType in allModuleAggrTypes) { mapping.FieldResolvers.AddRange(aggrType.Mappings[0].FieldResolvers); } // collect all fields from collected resolvers var allFields = mapping.FieldResolvers.Select(fr => fr.Field).ToList(); rootObjTypeDef.Fields.AddRange(allFields); // check for name duplicates var fieldNameDupes = rootObjTypeDef.Fields.Select(f => f.Name).GroupBy(fn => fn).Where(g => g.Count() > 1).ToList(); if (fieldNameDupes.Count > 0) { string dupesAll = string.Join(",", fieldNameDupes.Select(g => g.Key)); AddError($"Duplicate fields defined at top-level type {typeRole}, field names: {dupesAll}"); } // important: re-assign Index value for all fields; we moved fields to aggregate Query, Mutation // objects, so their indexes changed ReassignFieldIndexes(rootObjTypeDef); return(rootObjTypeDef); }
private Plan GetPlan(IExtendedDataRecord record, DataRecordInfo recordInfo) { Debug.Assert(null != record, "null IExtendedDataRecord"); Debug.Assert(null != recordInfo, "null DataRecordInfo"); Debug.Assert(null != recordInfo.RecordType, "null TypeUsage"); Plan[] plans = _lastPlans ?? (_lastPlans = new Plan[MaxPlanCount]); // find an existing plan in circular buffer int index = _lastPlanIndex - 1; for (int i = 0; i < MaxPlanCount; ++i) { index = (index + 1) % MaxPlanCount; if (null == plans[index]) { break; } if (plans[index].Key == recordInfo.RecordType) { _lastPlanIndex = index; return(plans[index]); } } Debug.Assert(0 <= index, "negative index"); Debug.Assert(index != _lastPlanIndex || (null == plans[index]), "index wrapped around"); // create a new plan ObjectTypeMapping mapping = System.Data.Common.Internal.Materialization.Util.GetObjectMapping(recordInfo.RecordType.EdmType, _workspace); Debug.Assert(null != mapping, "null ObjectTypeMapping"); Debug.Assert(Helper.IsComplexType(recordInfo.RecordType.EdmType), "IExtendedDataRecord is not ComplexType"); _lastPlanIndex = index; plans[index] = new Plan(recordInfo.RecordType, mapping, recordInfo.FieldMetadata); return(plans[index]); }
internal Plan(TypeUsage key, ObjectTypeMapping mapping, System.Collections.ObjectModel.ReadOnlyCollection <FieldMetadata> fields) { Debug.Assert(null != mapping, "null ObjectTypeMapping"); Debug.Assert(null != fields, "null FieldMetadata"); Key = key; Debug.Assert(!Helper.IsEntityType(mapping.ClrType), "Expecting complex type"); ClrType = LightweightCodeGenerator.GetConstructorDelegateForType((ClrComplexType)mapping.ClrType); Properties = new PlanEdmProperty[fields.Count]; int lastOrdinal = -1; for (int i = 0; i < Properties.Length; ++i) { FieldMetadata field = fields[i]; Debug.Assert(unchecked ((uint)field.Ordinal) < unchecked ((uint)fields.Count), "FieldMetadata.Ordinal out of range of Fields.Count"); Debug.Assert(lastOrdinal < field.Ordinal, "FieldMetadata.Ordinal is not increasing"); lastOrdinal = field.Ordinal; Properties[i] = new PlanEdmProperty(lastOrdinal, mapping.GetPropertyMap(field.FieldType.Name).ClrProperty); } }
internal static bool TryDetermineCSpaceModelType(Type type, MetadataWorkspace workspace, out EdmType modelEdmType) { Debug.Assert(null != workspace); Type nonNullabelType = TypeSystem.GetNonNullableType(type); // make sure the workspace knows about T workspace.ImplicitLoadAssemblyForType(nonNullabelType, System.Reflection.Assembly.GetCallingAssembly()); ObjectItemCollection objectItemCollection = (ObjectItemCollection)workspace.GetItemCollection(DataSpace.OSpace); EdmType objectEdmType; if (objectItemCollection.TryGetItem <EdmType>(nonNullabelType.FullName, out objectEdmType)) { Map map; if (workspace.TryGetMap(objectEdmType, DataSpace.OCSpace, out map)) { ObjectTypeMapping objectMapping = (ObjectTypeMapping)map; modelEdmType = objectMapping.EdmType; return(true); } } modelEdmType = null; return(false); }
} //method // we try to match field defined as method, by member/method name, even if GraphQL name is different; match: GraphQL ObjType.Member => Resolver.Member private void AssignResolversToMatchingResolverMethods(ObjectTypeMapping mapping) { var typeDef = mapping.TypeDef; foreach (var field in typeDef.Fields) { var fRes = mapping.GetResolver(field); if (fRes.IsMapped()) { continue; } if (field.ClrMember == null) { continue; //__typename has no clr member } var methName = field.ClrMember.Name; var resolverInfos = _allResolverMethods .Where(res => res.Module == mapping.TypeDef.Module) // in the same module! .Where(res => res.Method.Name.Equals(methName, StringComparison.OrdinalIgnoreCase)).ToList(); switch (resolverInfos.Count) { case 0: continue; // no match case 1: break; default: AddError($"Field {typeDef.Name}.{field.Name}: found more than one resolver method ({methName})."); continue; } //switch var resInfo = resolverInfos[0]; VerifyFieldResolverMethod(field, resInfo); var fldRes = mapping.GetResolver(field); fldRes.ResolverMethod = resInfo; } //foreach field } //method
internal override bool TryGetMember( StructuralType type, string memberName, bool ignoreCase, out EdmMember outMember) { outMember = (EdmMember)null; MappingBase map = (MappingBase)null; if (this.MetadataWorkspace.TryGetMap((GlobalItem)type, DataSpace.OCSpace, out map)) { ObjectTypeMapping objectTypeMapping = map as ObjectTypeMapping; if (objectTypeMapping != null) { ObjectMemberMapping memberMapForClrMember = objectTypeMapping.GetMemberMapForClrMember(memberName, ignoreCase); if (memberMapForClrMember != null) { outMember = memberMapForClrMember.EdmMember; return(true); } } } return(false); }
public static ObjectTypeMapping FindMapping(this TypeDefBase typeDef, Type fromType) { ObjectTypeMapping mapping = null; switch (typeDef) { case ObjectTypeDef otd: mapping = otd.FindObjectTypeMapping(fromType); break; case InterfaceTypeDef itd: mapping = FindObjectTypeMapping(itd.PossibleTypes, fromType); break; case UnionTypeDef utd: mapping = FindObjectTypeMapping(utd.PossibleTypes, fromType); break; default: // should never happen throw new Exception($"FATAL: Invalid target type kind {typeDef.Kind}, type {typeDef.Name}"); } return(mapping); }
internal Plan(TypeUsage key, ObjectTypeMapping mapping, ReadOnlyCollection <FieldMetadata> fields) { DebugCheck.NotNull(mapping); DebugCheck.NotNull(fields); Key = key; Debug.Assert(!Helper.IsEntityType(mapping.ClrType), "Expecting complex type"); ClrType = DelegateFactory.GetConstructorDelegateForType((ClrComplexType)mapping.ClrType); Properties = new PlanEdmProperty[fields.Count]; var lastOrdinal = -1; for (var i = 0; i < Properties.Length; ++i) { var field = fields[i]; Debug.Assert( unchecked ((uint)field.Ordinal) < unchecked ((uint)fields.Count), "FieldMetadata.Ordinal out of range of Fields.Count"); Debug.Assert(lastOrdinal < field.Ordinal, "FieldMetadata.Ordinal is not increasing"); lastOrdinal = field.Ordinal; Properties[i] = new PlanEdmProperty(lastOrdinal, mapping.GetPropertyMap(field.FieldType.Name).ClrProperty); } }
// setup resolvers having [ResolvesField] attribute private void AssignResolversByMethodsResolvesFieldAttribute(IList <ObjectTypeDef> types) { // go thru resolver classes, find methods with ResolvesField attr foreach (var resMethInfo in _allResolverMethods) { var resAttr = resMethInfo.ResolvesAttribute; if (resAttr == null) { continue; } var module = resMethInfo.Module; var fieldName = resAttr.FieldName.FirstLower(); FieldDef field = null; var typeDefs = types.Where(t => t.Module == resMethInfo.Module).OfType <ObjectTypeDef>(); // check target type if (resAttr.TargetType != null) { var typeDef = typeDefs.FirstOrDefault(td => td.ClrType == resAttr.TargetType); if (typeDef == null) { AddError($"Resolver method '{resMethInfo}': target type '{resAttr.TargetType}' not registered or is not Object type."); continue; } // match field field = typeDef.Fields.FirstOrDefault(f => f.Name == fieldName); if (field == null) { AddError($"Resolver method '{resMethInfo}': target field '{fieldName}' not found " + $"on type '{resAttr.TargetType}'."); continue; } } else { // TargetType is null - find match by name only var fields = typeDefs.SelectMany(t => t.Fields).Where(f => f.Name == fieldName).ToList(); switch (fields.Count) { case 1: field = fields[0]; break; case 0: AddError($"Resolver method '{resMethInfo}': target field '{fieldName}' not found on any object type."); continue; default: AddError($"Resolver method '{resMethInfo}': multipe target fields '{fieldName}' found on Object types."); continue; } } // We have a field; verify method is compatible VerifyFieldResolverMethod(field, resMethInfo); // get parent arg type and find mapping var objTypeDef = (ObjectTypeDef)field.OwnerType; ObjectTypeMapping mapping = null; switch (objTypeDef.TypeRole) { case TypeRole.ModuleQuery: case TypeRole.ModuleMutation: case TypeRole.ModuleSubscription: mapping = objTypeDef.Mappings[0]; break; case TypeRole.Data: var prms = resMethInfo.Method.GetParameters(); if (prms.Length < 2) { AddError($"Resolver method '{resMethInfo}', expected at least 2 parameters - field context and parent entity."); continue; } var parentEntType = prms[1].ParameterType; mapping = objTypeDef.Mappings.FirstOrDefault(m => m.EntityType.IsAssignableFrom(parentEntType)); if (mapping == null) { AddError($"Resolver method '{resMethInfo}', parent entity argument type '{parentEntType}' is not mapped to output GraphQL type '{objTypeDef.Name}'."); continue; } break; default: AddError($"Resolver method '{resMethInfo}', invalid target GraphQL type: '{objTypeDef.Name}'."); continue; }//switch var fldResolver = mapping.GetResolver(field); if (fldResolver == null) { AddError($"Resolver method '{resMethInfo}', failed to match to field resolver in type '{objTypeDef.Name}'."); continue; } if (fldResolver.ResolverMethod != null) { AddError($"Field '{fldResolver.Field}': more than one resolver method specified."); continue; } fldResolver.ResolverMethod = resMethInfo; //assign resolver } //foreach resMeth } //method
//HashSet<string> _keys = new HashSet<string>(); public OutputObjectScope(RequestPath path, object entity, ObjectTypeMapping mapping) { Path = path; Entity = entity; Mapping = mapping; }
// <summary> // Retrieves a mapping to CLR type for the given EDM type. Assumes the MetadataWorkspace has no // </summary> internal static ObjectTypeMapping GetObjectMapping(EdmType type, MetadataWorkspace workspace) { // Check if the workspace has cspace item collection registered with it. If not, then its a case // of public materializer trying to create objects from PODR or EntityDataReader with no context. ItemCollection collection; if (workspace.TryGetItemCollection(DataSpace.CSpace, out collection)) { return((ObjectTypeMapping)workspace.GetMap(type, DataSpace.OCSpace)); } else { EdmType ospaceType; EdmType cspaceType; // If its a case of EntityDataReader with no context, the typeUsage which is passed in must contain // a cspace type. We need to look up an OSpace type in the ospace item collection and then create // ocMapping if (type.DataSpace == DataSpace.CSpace) { // if its a primitive type, then the names will be different for CSpace type and OSpace type if (Helper.IsPrimitiveType(type)) { ospaceType = workspace.GetMappedPrimitiveType(((PrimitiveType)type).PrimitiveTypeKind, DataSpace.OSpace); } else { // Metadata will throw if there is no item with this identity present. // Is this exception fine or does object materializer code wants to wrap and throw a new exception ospaceType = workspace.GetItem <EdmType>(type.FullName, DataSpace.OSpace); } cspaceType = type; } else { // In case of PODR, there is no cspace at all. We must create a fake ocmapping, with ospace types // on both the ends ospaceType = type; cspaceType = type; } // This condition must be hit only when someone is trying to materialize a legacy data reader and we // don't have the CSpace metadata. if (!Helper.IsPrimitiveType(ospaceType) && !Helper.IsEntityType(ospaceType) && !Helper.IsComplexType(ospaceType)) { throw new NotSupportedException(Strings.Materializer_UnsupportedType); } ObjectTypeMapping typeMapping; if (Helper.IsPrimitiveType(ospaceType)) { typeMapping = new ObjectTypeMapping(ospaceType, cspaceType); } else { typeMapping = DefaultObjectMappingItemCollection.LoadObjectMapping(cspaceType, ospaceType, null); } return(typeMapping); } }