/// <summary>
        ///     Creates a delegate that will set the value of this property.
        /// </summary>
        /// <returns> The delegate. </returns>
        protected override Action <object, object> CreateSetter()
        {
            var parentGetter = _parentPropertyEntry.Getter;

            if (parentGetter == null)
            {
                return(null);
            }

            Action <object, object> setter;

            if (!DbHelpers.GetPropertySetters(EntryMetadata.DeclaringType).TryGetValue(Name, out setter))
            {
                return(null);
            }

            return((o, v) =>
            {
                var parent = parentGetter(o);
                if (parent == null)
                {
                    throw Error.DbPropertyValues_CannotSetPropertyOnNullCurrentValue(
                        Name, ParentPropertyEntry.Name);
                }
                setter(parentGetter(o), v);
            });
        }
        /// <summary>
        ///     Creates an object of the underlying type for this dictionary and hydrates it with property
        ///     values from this dictionary.
        /// </summary>
        /// <returns> The properties of this dictionary copied into a new object. </returns>
        public object ToObject()
        {
            // Create an instance of the object either using the CreateObject method for an entity or
            // a compiled delegate call to the constructor for other types.
            var clone   = CreateObject();
            var setters = DbHelpers.GetPropertySetters(_type);

            foreach (var propertyName in PropertyNames)
            {
                var value = GetItem(propertyName).Value;

                var asValues = value as InternalPropertyValues;
                if (asValues != null)
                {
                    value = asValues.ToObject();
                }

                // If the CLR type doesn't have a property with the given name, then we simply ignore it.
                // This cannot happen currently but will be possible when we have shadow state.
                Action <object, object> setterDelegate;
                if (setters.TryGetValue(propertyName, out setterDelegate))
                {
                    setterDelegate(clone, value);
                }
            }
            return(clone);
        }
Example #3
0
        /// <summary>
        ///     Creates a delegate that will set the value of this property.
        /// </summary>
        /// <returns> The delegate. </returns>
        protected override Action <object, object> CreateSetter()
        {
            Action <object, object> setter;

            DbHelpers.GetPropertySetters(InternalEntityEntry.EntityType).TryGetValue(Name, out setter);
            return(setter); // May be null
        }
Example #4
0
        protected override Action <object, object> CreateSetter()
        {
            Action <object, object> action;

            DbHelpers.GetPropertySetters(this.InternalEntityEntry.EntityType).TryGetValue(this.Name, out action);
            return(action);
        }
Example #5
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));
        }
Example #6
0
        public object ToObject()
        {
            object obj1 = this.CreateObject();
            IDictionary <string, Action <object, object> > propertySetters = DbHelpers.GetPropertySetters(this._type);

            foreach (string propertyName in (IEnumerable <string>) this.PropertyNames)
            {
                object obj2 = this.GetItem(propertyName).Value;
                InternalPropertyValues internalPropertyValues = obj2 as InternalPropertyValues;
                if (internalPropertyValues != null)
                {
                    obj2 = internalPropertyValues.ToObject();
                }
                Action <object, object> action;
                if (propertySetters.TryGetValue(propertyName, out action))
                {
                    action(obj1, obj2);
                }
            }
            return(obj1);
        }
Example #7
0
        protected override Action <object, object> CreateSetter()
        {
            Func <object, object> parentGetter = this._parentPropertyEntry.Getter;

            if (parentGetter == null)
            {
                return((Action <object, object>)null);
            }
            Action <object, object> setter;

            if (!DbHelpers.GetPropertySetters(this.EntryMetadata.DeclaringType).TryGetValue(this.Name, out setter))
            {
                return((Action <object, object>)null);
            }
            return((Action <object, object>)((o, v) =>
            {
                if (parentGetter(o) == null)
                {
                    throw Error.DbPropertyValues_CannotSetPropertyOnNullCurrentValue((object)this.Name, (object)this.ParentPropertyEntry.Name);
                }
                setter(parentGetter(o), v);
            }));
        }
Example #8
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));
        }