internal PlanEdmProperty(int ordinal, EdmProperty property) { Debug.Assert(0 <= ordinal, "negative ordinal"); Debug.Assert(null != property, "unsupported shadow state"); this.Ordinal = ordinal; this.GetExistingComplex = Helper.IsComplexType(property.TypeUsage.EdmType) ? LightweightCodeGenerator.GetGetterDelegateForProperty(property) : null; this.ClrProperty = LightweightCodeGenerator.GetSetterDelegateForProperty(property); }
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 EntityProxyTypeInfo(Type proxyType, ClrEntityType ospaceEntityType, DynamicMethod initializeCollections, List <PropertyInfo> baseGetters, List <PropertyInfo> baseSetters) { Debug.Assert(proxyType != null, "proxyType must be non-null"); _proxyType = proxyType; _entityType = ospaceEntityType; _initializeCollections = initializeCollections; _navigationPropertyAssociationTypes = new Dictionary <Tuple <string, string>, AssociationType>(); foreach (NavigationProperty navigationProperty in ospaceEntityType.NavigationProperties) { _navigationPropertyAssociationTypes.Add( new Tuple <string, string>( navigationProperty.RelationshipType.FullName, navigationProperty.ToEndMember.Name), (AssociationType)navigationProperty.RelationshipType); if (navigationProperty.RelationshipType.Name != navigationProperty.RelationshipType.FullName) { // Sometimes there isn't enough metadata to have a container name // Default codegen doesn't qualify names _navigationPropertyAssociationTypes.Add( new Tuple <string, string>( navigationProperty.RelationshipType.Name, navigationProperty.ToEndMember.Name), (AssociationType)navigationProperty.RelationshipType); } } FieldInfo entityWrapperField = proxyType.GetField(EntityWrapperFieldName, BindingFlags.DeclaredOnly | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); ParameterExpression Object_Parameter = Expression.Parameter(typeof(object), "proxy"); ParameterExpression Value_Parameter = Expression.Parameter(typeof(object), "value"); Debug.Assert(entityWrapperField != null, "entityWrapperField does not exist"); // Create the Wrapper Getter Expression <Func <object, object> > lambda = Expression.Lambda <Func <object, object> >( Expression.Field( Expression.Convert(Object_Parameter, entityWrapperField.DeclaringType), entityWrapperField), Object_Parameter); Func <object, object> getEntityWrapperDelegate = lambda.Compile(); Proxy_GetEntityWrapper = (object proxy) => { // This code validates that the wrapper points to the proxy that holds the wrapper. // This guards against mischief by switching this wrapper out for another one obtained // from a different object. IEntityWrapper wrapper = ((IEntityWrapper)getEntityWrapperDelegate(proxy)); if (wrapper != null && !object.ReferenceEquals(wrapper.Entity, proxy)) { throw new InvalidOperationException(System.Data.Entity.Strings.EntityProxyTypeInfo_ProxyHasWrongWrapper); } return(wrapper); }; // Create the Wrapper setter Proxy_SetEntityWrapper = Expression.Lambda <Func <object, object, object> >( Expression.Assign( Expression.Field( Expression.Convert(Object_Parameter, entityWrapperField.DeclaringType), entityWrapperField), Value_Parameter), Object_Parameter, Value_Parameter).Compile(); ParameterExpression PropertyName_Parameter = Expression.Parameter(typeof(string), "propertyName"); MethodInfo baseGetterMethod = proxyType.GetMethod("GetBasePropertyValue", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(string) }, null); if (baseGetterMethod != null) { _baseGetter = Expression.Lambda <Func <object, string, object> >( Expression.Call(Expression.Convert(Object_Parameter, proxyType), baseGetterMethod, PropertyName_Parameter), Object_Parameter, PropertyName_Parameter).Compile(); } ParameterExpression PropertyValue_Parameter = Expression.Parameter(typeof(object), "propertyName"); MethodInfo baseSetterMethod = proxyType.GetMethod("SetBasePropertyValue", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(string), typeof(object) }, null); if (baseSetterMethod != null) { _baseSetter = Expression.Lambda <Action <object, string, object> >( Expression.Call(Expression.Convert(Object_Parameter, proxyType), baseSetterMethod, PropertyName_Parameter, PropertyValue_Parameter), Object_Parameter, PropertyName_Parameter, PropertyValue_Parameter).Compile(); } _propertiesWithBaseGetter = new HashSet <string>(baseGetters.Select(p => p.Name)); _propertiesWithBaseSetter = new HashSet <string>(baseSetters.Select(p => p.Name)); _createObject = LightweightCodeGenerator.CreateConstructor(proxyType) as Func <object>; }