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>;
        }