public void SetValues(object value) { IDictionary <string, Func <object, object> > propertyGetters = DbHelpers.GetPropertyGetters(value.GetType()); foreach (string propertyName in (IEnumerable <string>) this.PropertyNames) { Func <object, object> func; if (propertyGetters.TryGetValue(propertyName, out func)) { object newValue = func(value); IPropertyValuesItem propertyValuesItem = this.GetItem(propertyName); if (newValue == null && propertyValuesItem.IsComplex) { throw Error.DbPropertyValues_ComplexObjectCannotBeNull((object)propertyName, (object)this._type.Name); } InternalPropertyValues internalPropertyValues = propertyValuesItem.Value as InternalPropertyValues; if (internalPropertyValues == null) { this.SetValue(propertyValuesItem, newValue); } else { internalPropertyValues.SetValues(newValue); } } } }
/// <summary> /// Creates a delegate that will get the value of this property. /// </summary> /// <returns> The delegate. </returns> protected override Func <object, object> CreateGetter() { Func <object, object> getter; DbHelpers.GetPropertyGetters(InternalEntityEntry.EntityType).TryGetValue(Name, out getter); return(getter); // May be null }
/// <summary> /// Sets the values of this dictionary by reading values out of the given object. /// The given object must be of the type that this dictionary is based on. /// </summary> /// <param name="value"> The object to read values from. </param> public void SetValues(object value) { DebugCheck.NotNull(value); var getters = DbHelpers.GetPropertyGetters(value.GetType()); foreach (var propertyName in PropertyNames) { // 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. Func <object, object> getterDelegate; if (getters.TryGetValue(propertyName, out getterDelegate)) { var propertyValue = getterDelegate(value); var item = GetItem(propertyName); // Cannot set values from a null complex property. if (propertyValue == null && item.IsComplex) { throw Error.DbPropertyValues_ComplexObjectCannotBeNull(propertyName, _type.Name); } var nestedValues = item.Value as InternalPropertyValues; if (nestedValues == null) { SetValue(item, propertyValue); } else { nestedValues.SetValues(propertyValue); } } } }
protected override Func <object, object> CreateGetter() { Func <object, object> func; DbHelpers.GetPropertyGetters(this.InternalEntityEntry.EntityType).TryGetValue(this.Name, out func); return(func); }
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> /// Creates a delegate that will get the value of this property. /// </summary> /// <returns> The delegate. </returns> protected override Func <object, object> CreateGetter() { var parentGetter = _parentPropertyEntry.Getter; if (parentGetter == null) { return(null); } Func <object, object> getter; if (!DbHelpers.GetPropertyGetters(EntryMetadata.DeclaringType).TryGetValue(Name, out getter)) { return(null); } return(o => { var parent = parentGetter(o); return parent == null ? null : getter(parent); }); }
protected override Func <object, object> CreateGetter() { Func <object, object> parentGetter = this._parentPropertyEntry.Getter; if (parentGetter == null) { return((Func <object, object>)null); } Func <object, object> getter; if (!DbHelpers.GetPropertyGetters(this.EntryMetadata.DeclaringType).TryGetValue(this.Name, out getter)) { return((Func <object, object>)null); } return((Func <object, object>)(o => { object obj = parentGetter(o); if (obj != null) { return getter(obj); } return (object)null; })); }
// <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)); }