public static PropertyEntryMetadata ValidateNameAndGetMetadata( InternalContext internalContext, Type declaringType, Type requestedType, string propertyName) { Type type; DbHelpers.GetPropertyTypes(declaringType).TryGetValue(propertyName, out type); MetadataWorkspace metadataWorkspace = internalContext.ObjectContext.MetadataWorkspace; StructuralType structuralType = metadataWorkspace.GetItem <StructuralType>(declaringType.FullNameWithNesting(), DataSpace.OSpace); bool isMapped = false; bool isComplex = false; EdmMember edmMember; structuralType.Members.TryGetValue(propertyName, false, out edmMember); if (edmMember != null) { EdmProperty edmProperty = edmMember as EdmProperty; if (edmProperty == null) { return((PropertyEntryMetadata)null); } if (type == (Type)null) { PrimitiveType edmType = edmProperty.TypeUsage.EdmType as PrimitiveType; type = edmType == null ? ((ObjectItemCollection)metadataWorkspace.GetItemCollection(DataSpace.OSpace)).GetClrType((StructuralType)edmProperty.TypeUsage.EdmType) : edmType.ClrEquivalentType; } isMapped = true; isComplex = edmProperty.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.ComplexType; } else { IDictionary <string, Func <object, object> > propertyGetters = DbHelpers.GetPropertyGetters(declaringType); IDictionary <string, Action <object, object> > propertySetters = DbHelpers.GetPropertySetters(declaringType); if (!propertyGetters.ContainsKey(propertyName) && !propertySetters.ContainsKey(propertyName)) { return((PropertyEntryMetadata)null); } } if (!requestedType.IsAssignableFrom(type)) { throw Error.DbEntityEntry_WrongGenericForProp((object)propertyName, (object)declaringType.Name, (object)requestedType.Name, (object)type.Name); } return(new PropertyEntryMetadata(declaringType, type, propertyName, isMapped, isComplex)); }
// <summary> // Validates that the given name is a property of the declaring type (either on the CLR type or in the EDM) // and that it is a complex or scalar property rather than a nav property and then returns metadata about // the property. // </summary> // <param name="internalContext"> The internal context. </param> // <param name="declaringType"> The type that the property is declared on. </param> // <param name="requestedType"> The type of property requested, which may be 'object' if any type can be accepted. </param> // <param name="propertyName"> Name of the property. </param> // <returns> Metadata about the property, or null if the property does not exist or is a navigation property. </returns> public static PropertyEntryMetadata ValidateNameAndGetMetadata( InternalContext internalContext, Type declaringType, Type requestedType, string propertyName) { DebugCheck.NotNull(internalContext); DebugCheck.NotNull(declaringType); DebugCheck.NotNull(requestedType); DebugCheck.NotEmpty(propertyName); Type propertyType; DbHelpers.GetPropertyTypes(declaringType).TryGetValue(propertyName, out propertyType); var metadataWorkspace = internalContext.ObjectContext.MetadataWorkspace; var edmType = metadataWorkspace.GetItem <StructuralType>(declaringType.FullNameWithNesting(), DataSpace.OSpace); var isMapped = false; var isComplex = false; EdmMember member; edmType.Members.TryGetValue(propertyName, false, out member); if (member != null) { // If the property is in the model, then it must be a scalar or complex property, not a nav prop var edmProperty = member as EdmProperty; if (edmProperty == null) { return(null); } if (propertyType == null) { var asPrimitive = edmProperty.TypeUsage.EdmType as PrimitiveType; if (asPrimitive != null) { propertyType = asPrimitive.ClrEquivalentType; } else { Debug.Assert( edmProperty.TypeUsage.EdmType is StructuralType, "Expected a structural type if property type is not primitive."); var objectItemCollection = (ObjectItemCollection)metadataWorkspace.GetItemCollection(DataSpace.OSpace); propertyType = objectItemCollection.GetClrType((StructuralType)edmProperty.TypeUsage.EdmType); } } isMapped = true; isComplex = edmProperty.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.ComplexType; } else { // If the prop is not in the model, then it must have a getter or a setter var propertyGetters = DbHelpers.GetPropertyGetters(declaringType); var propertySetters = DbHelpers.GetPropertySetters(declaringType); if (!(propertyGetters.ContainsKey(propertyName) || propertySetters.ContainsKey(propertyName))) { return(null); } Debug.Assert(propertyType != null, "If the property has a getter or setter, then it must exist and have a type."); } if (!requestedType.IsAssignableFrom(propertyType)) { throw Error.DbEntityEntry_WrongGenericForProp( propertyName, declaringType.Name, requestedType.Name, propertyType.Name); } return(new PropertyEntryMetadata(declaringType, propertyType, propertyName, isMapped, isComplex)); }