Exemplo n.º 1
0
        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));
        }
Exemplo n.º 2
0
        // <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));
        }