private void EmitField(CodeTypeDeclaration typeDecl, CodeTypeReference fieldType, bool hasDefault)
        {
            CodeMemberField memberField = new CodeMemberField(fieldType, Utils.FieldNameFromPropName(Item.Name));

            memberField.Attributes = MemberAttributes.Private;

            AttributeEmitter.AddGeneratedCodeAttribute(memberField);

            if (hasDefault)
            {
                if (this.Generator.UseDataServiceCollection)
                {
                    // new DataServiceCollection<T>(null, System.Data.Services.Client.TrackingMode.None, null, null, null);
                    // declare type is DataServiceCollection<T>
                    Debug.Assert(fieldType.TypeArguments.Count == 1, "Declare type is non generic.");

                    // new DataServiceCollection<[type]>(null, TrackingMode.None)
                    memberField.InitExpression = new CodeObjectCreateExpression(
                        fieldType,
                        new CodePrimitiveExpression(null),
                        new CodeFieldReferenceExpression(
                            new CodeTypeReferenceExpression(typeof(System.Data.Services.Client.TrackingMode)),
                            "None"));
                }
                else
                {
                    memberField.InitExpression = new CodeObjectCreateExpression(fieldType);
                }
            }

            typeDecl.Members.Add(memberField);
        }
Example #2
0
        private void AddRootNamespaceField(CodeTypeDeclaration typeDecl)
        {
            // Add this field (VB declaration), where known client type name is ClientNS.BikesEntities
            // ROOTNAMESPACE = GetType(ClientNS.BikesEntities).Namespace.Remove(GetType(ClientNS.BikesEntities).Namespace.LastIndexOf("ClientNS"))

            EntityContainer container          = (EntityContainer)this.Item;
            string          containerNamespace = Generator.GetClientTypeNamespace(this.Generator.GetContainerNamespace(container));
            // VB-ism: if namespace and type names are the same (Blah.Blah), GetType(Blah.Blah) fails...
            string vbScopedcontainerName = (string.IsNullOrEmpty(containerNamespace) || container.Name.Equals(containerNamespace, StringComparison.OrdinalIgnoreCase))
                                           ? container.Name : (containerNamespace + "." + container.Name);


            CodeExpression namespaceAccess = new CodePropertyReferenceExpression(
                new CodeTypeOfExpression(vbScopedcontainerName),
                "Namespace");

            CodeMemberField rootNamespaceField = new CodeMemberField(
                TypeReference.ForType(typeof(string)),
                "ROOTNAMESPACE");

            rootNamespaceField.Attributes     = MemberAttributes.Static | MemberAttributes.Private;
            rootNamespaceField.InitExpression = new CodeMethodInvokeExpression(
                namespaceAccess,
                "Remove",
                new CodeMethodInvokeExpression(
                    namespaceAccess,
                    "LastIndexOf",
                    new CodePrimitiveExpression(containerNamespace)));
            AttributeEmitter.AddGeneratedCodeAttribute(rootNamespaceField);
            typeDecl.Members.Add(rootNamespaceField);
        }
Example #3
0
        /// <summary>
        /// Creates the necessary constructors for the entity container.
        /// </summary>
        private void CreateConstructors(CodeTypeDeclaration typeDecl, bool setupTypeMapper, bool hasInheritance)
        {
            // Constructor that takes a uri
            //
            // public ctor(System.Uri serviceRoot)
            //    : base(serviceRoot)
            // {
            //      this.OnContextCreated();
            // }
            CodeConstructor connectionWorkspaceCtor = new CodeConstructor();

            connectionWorkspaceCtor.Attributes = MemberAttributes.Public;
            CodeParameterDeclarationExpression connectionParam = new CodeParameterDeclarationExpression(TypeReference.FromString("System.Uri", true), "serviceRoot");

            connectionWorkspaceCtor.Parameters.Add(connectionParam);
            connectionWorkspaceCtor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression(connectionParam.Name));

            AttributeEmitter.AddGeneratedCodeAttribute(connectionWorkspaceCtor);

            CommentEmitter.EmitSummaryComments(Strings.CtorSummaryComment(Item.Name), connectionWorkspaceCtor.Comments);

            // If we have an externally provided namespage (e.g. from Visual Studio), we need to
            // inject a type-mapper because type names won't match between client and server
            if (setupTypeMapper || hasInheritance)
            {
                connectionWorkspaceCtor.Statements.Add(
                    new CodeAssignStatement(
                        new CodeFieldReferenceExpression(ThisRef, "ResolveName"),
                        new CodeDelegateCreateExpression(
                            TypeReference.ForType(typeof(Func <,>), TypeReference.ForType(typeof(Type)), TypeReference.ForType(typeof(String))),
                            ThisRef,
                            "ResolveNameFromType"
                            )
                        )
                    );
            }

            if (setupTypeMapper)
            {
                connectionWorkspaceCtor.Statements.Add(
                    new CodeAssignStatement(
                        new CodeFieldReferenceExpression(ThisRef, "ResolveType"),
                        new CodeDelegateCreateExpression(
                            TypeReference.ForType(typeof(Func <,>), TypeReference.ForType(typeof(String)), TypeReference.ForType(typeof(Type))),
                            ThisRef,
                            "ResolveTypeFromName"
                            )
                        )
                    );
            }

            connectionWorkspaceCtor.Statements.Add(OnContextCreatedCodeMethodInvokeExpression());

            typeDecl.Members.Add(connectionWorkspaceCtor);
        }
        public ClientApiGenerator(Schema sourceSchema, EdmItemCollection edmItemCollection, EntityClassGenerator generator, List<EdmSchemaError> errors)
        {
            Debug.Assert(sourceSchema != null, "sourceSchema is null");
            Debug.Assert(edmItemCollection != null, "edmItemCollection is null");
            Debug.Assert(generator != null, "generator is null");
            Debug.Assert(errors != null, "errors is null");

            _edmItemCollection = edmItemCollection;
            _sourceSchema = sourceSchema;
            _generator = generator;
            _errors = errors;
            _attributeEmitter = new AttributeEmitter(_typeReference);
        }
Example #5
0
        /// <summary>
        /// Creates the CodeTypeDeclarations necessary to generate the code
        /// </summary>
        public void Emit()
        {
            // it is a valid scenario for namespaceName to be empty
            string namespaceName = Generator.SourceObjectNamespaceName;

            // emit the namespace definition
            CodeNamespace codeNamespace = new CodeNamespace(namespaceName);

            // output some boiler plate comments
            string comments = Strings.NamespaceComments(
                System.IO.Path.GetFileName(_targetFilePath),
                DateTime.Now.ToString(System.Globalization.CultureInfo.CurrentCulture));

            CommentEmitter.EmitComments(CommentEmitter.GetFormattedLines(comments, false), codeNamespace.Comments, false);
            CompileUnit.Namespaces.Add(codeNamespace);

            // Add the assembly attribute.
            CodeAttributeDeclaration assemblyAttribute;

            // SQLBUDT 505339: VB compiler fails if multiple assembly attributes exist in the same project.
            // This adds a GUID to the assembly attribute so that each generated file will have a unique EdmSchemaAttribute in VB.
            if (this.Generator.Language == System.Data.Entity.Design.LanguageOption.GenerateVBCode) //The GUID is only added in VB
            {
                assemblyAttribute = AttributeEmitter.EmitSimpleAttribute("System.Data.Objects.DataClasses.EdmSchemaAttribute", System.Guid.NewGuid().ToString());
            }
            else
            {
                assemblyAttribute = AttributeEmitter.EmitSimpleAttribute("System.Data.Objects.DataClasses.EdmSchemaAttribute");
            }
            CompileUnit.AssemblyCustomAttributes.Add(assemblyAttribute);

            Dictionary <string, string> usedClassName = new Dictionary <string, string>(StringComparer.Ordinal);

            // Emit the classes in the schema
            foreach (GlobalItem element in Generator.GetSourceTypes())
            {
                Debug.Assert(!(element is EdmFunction), "Are you trying to emit functions now? If so add an emitter for it.");

                if (AddElementNameToCache(element, usedClassName))
                {
                    SchemaTypeEmitter             emitter         = CreateElementEmitter(element);
                    CodeTypeDeclarationCollection typeDeclaration = emitter.EmitApiClass();
                    if (typeDeclaration.Count > 0)
                    {
                        codeNamespace.Types.AddRange(typeDeclaration);
                    }
                }
            }
        }
Example #6
0
        /// <summary>
        /// Shared code for adding a EdmTypeAttribute derived attribute including parameters to a type or property
        /// </summary>
        /// <param name="attributeName">Unqualified name of the attribute</param>
        /// <param name="type">The type or property type of the code that is having the attribute attached.</param>
        /// <param name="member">The type declaration to add the attribues to.</param>
        public void EmitSchemaTypeAttribute(string attributeName, EdmType type, CodeTypeMember member)
        {
            Debug.Assert(attributeName != null, "attributeName should not be null");
            Debug.Assert(type != null, "type should not be null");
            Debug.Assert(member != null, "typeDecl should not be null");

            // [mappingattribute(SchemaName="namespace",TypeName="classname")
            CodeAttributeDeclaration attribute = EmitSimpleAttribute(attributeName);

            AttributeEmitter.AddNamedAttributeArguments(attribute,
                                                        "NamespaceName", type.NamespaceName,
                                                        "Name", type.Name);

            member.CustomAttributes.Add(attribute);
        }
Example #7
0
        /// <summary>
        /// The method to be called to create the type level attributes for the ItemTypeEmitter
        /// </summary>
        /// <param name="emitter">The strongly typed emitter</param>
        /// <param name="typeDecl">The type declaration to add the attribues to.</param>
        public void EmitTypeAttributes(EntityTypeEmitter emitter, CodeTypeDeclaration typeDecl)
        {
            Debug.Assert(emitter != null, "emitter should not be null");
            Debug.Assert(typeDecl != null, "typeDecl should not be null");

            EmitSchemaTypeAttribute(FQAdoFrameworkDataClassesName("EdmEntityTypeAttribute"), emitter, typeDecl);

            CodeAttributeDeclaration attribute2 = EmitSimpleAttribute("System.Runtime.Serialization.DataContractAttribute");

            AttributeEmitter.AddNamedAttributeArguments(attribute2,
                                                        "IsReference", true);
            typeDecl.CustomAttributes.Add(attribute2);

            CodeAttributeDeclaration attribute3 = EmitSimpleAttribute("System.Serializable");

            typeDecl.CustomAttributes.Add(attribute3);

            EmitKnownTypeAttributes(emitter.Item, emitter.Generator, typeDecl);
        }
Example #8
0
        private CodeMemberField CreateEntitySetField(EntitySet set)
        {
            Debug.Assert(set != null, "Field is Null");

            // trying to get
            //
            // private ObjectQuery<SpanTestsModel.Customer> _Customers = null;

            CodeMemberField codeField = new CodeMemberField();

            codeField.Attributes = MemberAttributes.Final | MemberAttributes.Private;
            codeField.Name       = Utils.FieldNameFromPropName(set.Name);
            AttributeEmitter.AddGeneratedCodeAttribute(codeField);

            CodeTypeReference genericParameter = Generator.GetLeastPossibleQualifiedTypeReference(set.ElementType);

            codeField.Type = TypeReference.AdoFrameworkGenericClass("DataServiceQuery", genericParameter);
            return(codeField);
        }
Example #9
0
        private void EmitField(CodeTypeDeclaration typeDecl, CodeTypeReference fieldType)
        {
            CodeMemberField memberField = new CodeMemberField(fieldType, FieldName);

            memberField.Attributes = MemberAttributes.Private;
            if (HasDefault(Item))
            {
                memberField.InitExpression = GetDefaultValueExpression(Item);
            }

            AttributeEmitter.AddGeneratedCodeAttribute(memberField);

            typeDecl.Members.Add(memberField);

            if (TypeSemantics.IsComplexType(Item.TypeUsage))
            {
                CodeMemberField complexInitField = new CodeMemberField(TypeReference.ForType(typeof(bool)), ComplexPropertyInitializedFieldName);
                complexInitField.Attributes = MemberAttributes.Private;
                AttributeEmitter.AddGeneratedCodeAttribute(complexInitField);
                typeDecl.Members.Add(complexInitField);
            }
        }
Example #10
0
        /// <summary>
        /// Create an AddTo-EntitysetName methiod for each entityset in the context.
        /// </summary>
        /// <param name="set">EntityContainerEntitySet that we will go over to get the existing entitysets.</param>
        /// <returns> Method definition </returns>

        private CodeMemberMethod CreateEntitySetAddObjectMethod(EntitySet set)
        {
            Debug.Assert(set != null, "Property is Null");

            // trying to get
            //
            // public void AddToCustomer(Customer customer)
            // {
            //      base.AddObject("Customer", customer);
            // }
            CodeMemberMethod codeMethod = new CodeMemberMethod();

            codeMethod.Attributes = MemberAttributes.Final | GetEntityTypeAccessibility(set.ElementType);
            codeMethod.Name       = ("AddTo" + set.Name);

            CodeParameterDeclarationExpression parameter = new CodeParameterDeclarationExpression();

            parameter.Type = Generator.GetLeastPossibleQualifiedTypeReference(set.ElementType);
            parameter.Name = Utils.CamelCase(set.ElementType.Name);
            parameter.Name = Utils.SetSpecialCaseForFxCopOnPropertyName(parameter.Name);
            codeMethod.Parameters.Add(parameter);

            codeMethod.ReturnType = new CodeTypeReference(typeof(void));

            AttributeEmitter.AddGeneratedCodeAttribute(codeMethod);

            codeMethod.Statements.Add(
                new CodeMethodInvokeExpression(
                    new CodeBaseReferenceExpression(),
                    "AddObject",
                    new CodePrimitiveExpression(set.Name),
                    new CodeFieldReferenceExpression(null, parameter.Name)
                    )
                );

            // method summary
            CommentEmitter.EmitSummaryComments(set, codeMethod.Comments);
            return(codeMethod);
        }
        public override CodeTypeDeclarationCollection EmitApiClass()
        {
            Debug.Assert(Item.AssociationEndMembers.Count == 2, "must have exactly two ends");

            AssociationEndMember end1 = Item.AssociationEndMembers[0];
            AssociationEndMember end2 = Item.AssociationEndMembers[1];

            Generator.CompileUnit.AssemblyCustomAttributes.Add(
                AttributeEmitter.EmitSimpleAttribute(
                    Utils.FQAdoFrameworkDataClassesName("EdmRelationshipAttribute"),
                    Item.NamespaceName, //it is ok to use the c namespace because relationships aren't backed by clr objects
                    Item.Name,
                    end1.Name,
                    GetMultiplicityCodeExpression(end1.RelationshipMultiplicity),
                    GetEndTypeCodeExpression(end1),
                    end2.Name,
                    GetMultiplicityCodeExpression(end2.RelationshipMultiplicity),
                    GetEndTypeCodeExpression(end2)
                    ));

            // this method doesn't actually create a new type, just a new assembly level attribute for each end
            return(new CodeTypeDeclarationCollection());
        }
Example #12
0
        /// <summary>
        /// The method to be called to create the property level attributes for the PropertyEmitter
        /// </summary>
        /// <param name="emitter">The strongly typed emitter</param>
        /// <param name="propertyDecl">The type declaration to add the attribues to.</param>
        /// <param name="additionalAttributes">Additional attributes to emit</param>
        public void EmitPropertyAttributes(PropertyEmitter emitter,
                                           CodeMemberProperty propertyDecl,
                                           List <CodeAttributeDeclaration> additionalAttributes)
        {
            if (MetadataUtil.IsPrimitiveType(emitter.Item.TypeUsage.EdmType) || MetadataUtil.IsEnumerationType(emitter.Item.TypeUsage.EdmType))
            {
                CodeAttributeDeclaration scalarPropertyAttribute = EmitSimpleAttribute(FQAdoFrameworkDataClassesName("EdmScalarPropertyAttribute"));

                if (emitter.IsKeyProperty)
                {
                    Debug.Assert(emitter.Item.Nullable == false, "An EntityKeyProperty cannot be nullable.");

                    AttributeEmitter.AddNamedAttributeArguments(scalarPropertyAttribute, "EntityKeyProperty", true);
                }

                if (!emitter.Item.Nullable)
                {
                    AttributeEmitter.AddNamedAttributeArguments(scalarPropertyAttribute, "IsNullable", false);
                }

                propertyDecl.CustomAttributes.Add(scalarPropertyAttribute);
            }
            else //Complex property
            {
                Debug.Assert(MetadataUtil.IsComplexType(emitter.Item.TypeUsage.EdmType) ||
                             (MetadataUtil.IsCollectionType(emitter.Item.TypeUsage.EdmType)),
                             "not a complex type or a collection type");
                CodeAttributeDeclaration attribute = EmitSimpleAttribute(FQAdoFrameworkDataClassesName("EdmComplexPropertyAttribute"));
                propertyDecl.CustomAttributes.Add(attribute);

                // Have CodeDOM serialization set the properties on the ComplexObject, not the ComplexObject instance.
                attribute = EmitSimpleAttribute("System.ComponentModel.DesignerSerializationVisibility");
                AttributeEmitter.AddAttributeArguments(attribute,
                                                       new object[] { new CodePropertyReferenceExpression(
                                                                          new CodeTypeReferenceExpression(TypeReference.ForType(
                                                                                                              typeof(System.ComponentModel.DesignerSerializationVisibility))), "Content") });
                propertyDecl.CustomAttributes.Add(attribute);

                if (!MetadataUtil.IsCollectionType(emitter.Item.TypeUsage.EdmType))
                {
                    // Non-collection complex properties also need additional serialization attributes to force them to be explicitly serialized if they are null
                    // If this is omitted, null complex properties do not get explicitly set to null during deserialization, which causes
                    // them to be lazily constructed once the property is accessed after the entity is deserialized. If the property is
                    // actually null during serialiation, that means the user has explicitly set it, so we need to maintain that during serialization.
                    // This doesn't apply to collection types because they aren't lazily constructed and don't need this extra information.
                    attribute = EmitSimpleAttribute("System.Xml.Serialization.XmlElement");
                    AttributeEmitter.AddNamedAttributeArguments(attribute, "IsNullable", true);
                    propertyDecl.CustomAttributes.Add(attribute);

                    attribute = EmitSimpleAttribute("System.Xml.Serialization.SoapElement");
                    AttributeEmitter.AddNamedAttributeArguments(attribute, "IsNullable", true);
                    propertyDecl.CustomAttributes.Add(attribute);
                }
            }

            // serialization attribute
            AddDataMemberAttribute(propertyDecl);

            if (additionalAttributes != null && additionalAttributes.Count > 0)
            {
                try
                {
                    propertyDecl.CustomAttributes.AddRange(additionalAttributes.ToArray());
                }
                catch (ArgumentNullException e)
                {
                    emitter.Generator.AddError(Strings.InvalidAttributeSuppliedForProperty(emitter.Item.Name),
                                               ModelBuilderErrorCode.InvalidAttributeSuppliedForProperty,
                                               EdmSchemaErrorSeverity.Error,
                                               e);
                }
            }

            EmitGeneratedCodeAttribute(propertyDecl);
        }
        /// <summary>
        /// Emit static factory method which creates an instance of the class and initializes
        /// non-nullable properties (taken as arguments)
        /// </summary>
        /// <param name="typeDecl"></param>
        protected virtual void EmitFactoryMethod(CodeTypeDeclaration typeDecl)
        {
            // build list of non-nullable properties
            ReadOnlyMetadataCollection <EdmProperty> properties = GetProperties();
            List <EdmProperty> parameters = new List <EdmProperty>(properties.Count);

            foreach (EdmProperty property in properties)
            {
                bool include = IncludeFieldInFactoryMethod(property);
                if (include)
                {
                    parameters.Add(property);
                }
            }

            // if there are no parameters, we don't emit anything (1 is for the null element)
            // nor do we emit everything if this is the Ref propertied ctor and the parameter list is the same as the many parametered ctor
            if (parameters.Count < 1)
            {
                return;
            }

            CodeMemberMethod        method  = new CodeMemberMethod();
            CodeTypeReference       typeRef = TypeReference.FromString(Item.Name);
            UniqueIdentifierService uniqueIdentifierService = new UniqueIdentifierService(Generator.IsLanguageCaseSensitive);
            string instanceName = uniqueIdentifierService.AdjustIdentifier(Utils.CamelCase(Item.Name));

            // public static Class CreateClass(...)
            method.Attributes = MemberAttributes.Static | MemberAttributes.Public;
            method.Name       = "Create" + Item.Name;
            if (NavigationPropertyEmitter.IsNameAlreadyAMemberName(Item, method.Name, Generator.LanguageAppropriateStringComparer))
            {
                Generator.AddError(Strings.GeneratedFactoryMethodNameConflict(method.Name, Item.Name),
                                   ModelBuilderErrorCode.GeneratedFactoryMethodNameConflict,
                                   EdmSchemaErrorSeverity.Error);
            }

            method.ReturnType = typeRef;
            AttributeEmitter.AddGeneratedCodeAttribute(method);

            // output method summary comments
            CommentEmitter.EmitSummaryComments(Strings.FactoryMethodSummaryComment(Item.Name), method.Comments);


            // Class class = new Class();
            CodeVariableDeclarationStatement createNewInstance = new CodeVariableDeclarationStatement(
                typeRef, instanceName, new CodeObjectCreateExpression(typeRef));

            method.Statements.Add(createNewInstance);
            CodeVariableReferenceExpression instanceRef = new CodeVariableReferenceExpression(instanceName);

            // iterate over the properties figuring out which need included in the factory method
            foreach (EdmProperty property in parameters)
            {
                // CreateClass( ... , propType propName ...)
                PropertyEmitter   propertyEmitter       = new PropertyEmitter(Generator, property, UsingStandardBaseClass);
                CodeTypeReference propertyTypeReference = propertyEmitter.PropertyType;
                String            parameterName         = uniqueIdentifierService.AdjustIdentifier(Utils.FixParameterName(propertyEmitter.PropertyName, "argument"));
                parameterName = Utils.SetSpecialCaseForFxCopOnPropertyName(parameterName);
                CodeParameterDeclarationExpression paramDecl = new CodeParameterDeclarationExpression(
                    propertyTypeReference, parameterName);
                CodeArgumentReferenceExpression paramRef = new CodeArgumentReferenceExpression(paramDecl.Name);
                method.Parameters.Add(paramDecl);

                // add comment describing the parameter
                CommentEmitter.EmitParamComments(paramDecl, Strings.FactoryParamCommentGeneral(propertyEmitter.PropertyName), method.Comments);

                CodeExpression newPropertyValue;
                if (TypeSemantics.IsComplexType(propertyEmitter.Item.TypeUsage))
                {
                    List <CodeExpression> complexVerifyParameters = new List <CodeExpression>();
                    complexVerifyParameters.Add(paramRef);
                    complexVerifyParameters.Add(new CodePrimitiveExpression(propertyEmitter.PropertyName));

                    // if (null == param) { throw new ArgumentNullException("PropertyName"); }
                    method.Statements.Add(
                        new CodeConditionStatement(
                            EmitExpressionEqualsNull(paramRef),
                            new CodeThrowExceptionStatement(
                                new CodeObjectCreateExpression(
                                    TypeReference.ForType(typeof(ArgumentNullException)),
                                    new CodePrimitiveExpression(parameterName)
                                    )
                                )
                            )
                        );

                    newPropertyValue = paramRef;
                }
                else
                {
                    newPropertyValue = paramRef;
                }

                // Scalar property:
                //     Property = param;
                // Complex property:
                //     Property = StructuralObject.VerifyComplexObjectIsNotNull(param, propertyName);

                method.Statements.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(instanceRef, propertyEmitter.PropertyName), newPropertyValue));
            }

            // return class;
            method.Statements.Add(new CodeMethodReturnStatement(instanceRef));

            // actually add the method to the class
            typeDecl.Members.Add(method);
        }
Example #14
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="memberProperty"></param>
 /// <param name="additionalAttributes">Additional attributes to emit</param>
 private void EmitCustomAttributes(CodeMemberProperty memberProperty,
                                   List <CodeAttributeDeclaration> additionalAttributes)
 {
     AttributeEmitter.AddGeneratedCodeAttribute(memberProperty);
     Generator.AttributeEmitter.EmitPropertyAttributes(this, memberProperty, additionalAttributes);
 }
Example #15
0
        private void CreateTypeMappingMethods(CodeTypeDeclaration typeDecl, bool needTypeMapper, bool hasInheritance)
        {
            // Special case to compensate for VB's "root namespace" feature.
            if (this.Generator.Language == LanguageOption.GenerateVBCode)
            {
                AddRootNamespaceField(typeDecl);
            }

            CodeExpression comparisonExpression = new CodePropertyReferenceExpression(
                new CodeTypeReferenceExpression(TypeReference.ForType(typeof(StringComparison))),
                Enum.GetName(typeof(StringComparison), this.Generator.LanguageAppropriateStringComparer));

            if (needTypeMapper)
            {
                CodeMemberMethod resolveTypeFromName = new CodeMemberMethod();
                resolveTypeFromName.Name       = "ResolveTypeFromName";
                resolveTypeFromName.Attributes = MemberAttributes.Final | MemberAttributes.Family;
                resolveTypeFromName.Parameters.Add(new CodeParameterDeclarationExpression(TypeReference.ForType(typeof(string)), "typeName"));
                resolveTypeFromName.ReturnType = TypeReference.ForType(typeof(Type));
                AttributeEmitter.AddGeneratedCodeAttribute(resolveTypeFromName);
                CommentEmitter.EmitSummaryComments(Strings.TypeMapperDescription, resolveTypeFromName.Comments);

                // NOTE: since multiple namespaces can have the same prefix and match the namespace
                // prefix condition, it's important that the prefix check is done is prefix-length
                // order, starting with the longest prefix.
                var pairs = this.Generator.NamespaceMap.OrderByDescending(p => p.Key.Length).ThenBy(p => p.Key);

                foreach (var pair in pairs)
                {
                    // Assuming pair.Key is "abc" and pair.Value is "def" and len(def)=3, generate:
                    // if (typeName.StartsWith("abc", StringComparison.Ordinal))
                    //     return this.GetType().Assembly.GetType(string.Concat("def", typeName.Substring(3)), false)
                    // DEVNOTE(Microsoft): we should use GetType(xxx, FALSE) here so it will not throw and fall back to null
                    // GetType(type, bool throw, bool ignoreCase) does not exist in SL, do not use!
                    resolveTypeFromName.Statements.Add(
                        new CodeConditionStatement(
                            new CodeMethodInvokeExpression(
                                new CodeVariableReferenceExpression("typeName"),
                                "StartsWith",
                                new CodePrimitiveExpression(pair.Key),
                                comparisonExpression
                                ),
                            new CodeMethodReturnStatement(
                                new CodeMethodInvokeExpression(
                                    new CodePropertyReferenceExpression(
                                        new CodeMethodInvokeExpression(
                                            ThisRef,
                                            "GetType"
                                            ),
                                        "Assembly"
                                        ),
                                    "GetType",
                                    new CodeMethodInvokeExpression(
                                        new CodeTypeReferenceExpression(TypeReference.ForType(typeof(string))),
                                        "Concat",
                                        this.LanguageSpecificNamespace(pair.Value),
                                        new CodeMethodInvokeExpression(
                                            new CodeVariableReferenceExpression("typeName"),
                                            "Substring",
                                            new CodePrimitiveExpression(pair.Key.Length)
                                            )
                                        ),
                                    new CodePrimitiveExpression(false)
                                    )
                                )
                            )
                        );
                }

                resolveTypeFromName.Statements.Add(
                    new CodeMethodReturnStatement(
                        new CodePrimitiveExpression(null)));

                typeDecl.Members.Add(resolveTypeFromName);
            }

            CodeMemberMethod resolveNameFromType = new CodeMemberMethod();

            resolveNameFromType.Name       = "ResolveNameFromType";
            resolveNameFromType.Attributes = MemberAttributes.Final | MemberAttributes.Family;
            resolveNameFromType.Parameters.Add(new CodeParameterDeclarationExpression(TypeReference.ForType(typeof(Type)), "clientType"));
            resolveNameFromType.ReturnType = TypeReference.ForType(typeof(String));
            AttributeEmitter.AddGeneratedCodeAttribute(resolveNameFromType);
            CommentEmitter.EmitSummaryComments(Strings.TypeMapperDescription, resolveNameFromType.Comments);

            // NOTE: in this case order also matters, but the length of the CLR
            // namespace is what needs to be considered.
            var reversePairs = Generator.NamespaceMap.OrderByDescending(p => p.Value.Length).ThenBy(p => p.Key);

            foreach (var pair in reversePairs)
            {
                // Assuming pair.Key is "abc" and pair.Value is "def", generate:
                // if (t.Namespace.Equals("def", StringComparison.Ordinal)) return string.Concat("abc.", t.Name);

                resolveNameFromType.Statements.Add(
                    new CodeConditionStatement(
                        new CodeMethodInvokeExpression(
                            new CodePropertyReferenceExpression(
                                new CodeVariableReferenceExpression("clientType"),
                                "Namespace"
                                ),
                            "Equals",
                            this.LanguageSpecificNamespace(pair.Value),
                            comparisonExpression
                            ),
                        new CodeMethodReturnStatement(
                            new CodeMethodInvokeExpression(
                                new CodeTypeReferenceExpression(TypeReference.ForType(typeof(string))),
                                "Concat",
                                new CodePrimitiveExpression(pair.Key + "."),
                                new CodePropertyReferenceExpression(
                                    new CodeVariableReferenceExpression("clientType"),
                                    "Name"
                                    )
                                )
                            )
                        )
                    );
            }

            if (hasInheritance)
            {
                CodeExpression clientTypeFullName = new CodePropertyReferenceExpression(
                    new CodeVariableReferenceExpression("clientType"),
                    "FullName");

                if (this.Generator.Language == LanguageOption.GenerateVBCode)
                {
                    // return clientType.FullName.Substring(ROOTNAMESPACE.Length);
                    resolveNameFromType.Statements.Add(
                        new CodeMethodReturnStatement(
                            new CodeMethodInvokeExpression(
                                clientTypeFullName,
                                "Substring",
                                new CodePropertyReferenceExpression(
                                    new CodeVariableReferenceExpression("ROOTNAMESPACE"),
                                    "Length"
                                    )
                                )
                            )
                        );
                }
                else
                {
                    // return clientType.FullName;
                    resolveNameFromType.Statements.Add(new CodeMethodReturnStatement(clientTypeFullName));
                }
            }
            else
            {
                resolveNameFromType.Statements.Add(
                    new CodeMethodReturnStatement(
                        NullExpression
                        )
                    );
            }

            typeDecl.Members.Add(resolveNameFromType);
        }
Example #16
0
        /// <summary>
        /// Generate a navigation property
        /// </summary>
        /// <param name="target">the other end</param>
        /// <param name="referenceProperty">True to emit Reference navigation property</param>
        /// <returns>the generated property</returns>
        private CodeMemberProperty EmitNavigationProperty(RelationshipEndMember target, bool referenceProperty)
        {
            CodeTypeReference typeRef = GetReturnType(target, referenceProperty);

            // raise the PropertyGenerated event
            PropertyGeneratedEventArgs eventArgs = new PropertyGeneratedEventArgs(Item,
                                                                                  null, // no backing field
                                                                                  typeRef);

            this.Generator.RaisePropertyGeneratedEvent(eventArgs);

            // [System.ComponentModel.Browsable(false)]
            // public TargetType TargetName
            // public EntityReference<TargetType> TargetName
            // or
            // public EntityCollection<targetType> TargetNames
            CodeMemberProperty property = new CodeMemberProperty();

            if (referenceProperty)
            {
                AttributeEmitter.AddBrowsableAttribute(property);
                Generator.AttributeEmitter.EmitGeneratedCodeAttribute(property);
            }
            else
            {
                Generator.AttributeEmitter.EmitNavigationPropertyAttributes(Generator, target, property, eventArgs.AdditionalAttributes);

                // Only reference navigation properties are currently currently supported with XML serialization
                // and thus we should use the XmlIgnore and SoapIgnore attributes on other property types.
                AttributeEmitter.AddIgnoreAttributes(property);
            }

            AttributeEmitter.AddDataMemberAttribute(property);

            CommentEmitter.EmitSummaryComments(Item, property.Comments);

            property.Name = Item.Name;
            if (referenceProperty)
            {
                property.Name += "Reference";
                if (IsNameAlreadyAMemberName(Item.DeclaringType, property.Name, Generator.LanguageAppropriateStringComparer))
                {
                    Generator.AddError(Strings.GeneratedNavigationPropertyNameConflict(Item.Name, Item.DeclaringType.Name, property.Name),
                                       ModelBuilderErrorCode.GeneratedNavigationPropertyNameConflict,
                                       EdmSchemaErrorSeverity.Error, Item.DeclaringType.FullName, property.Name);
                }
            }

            if (eventArgs.ReturnType != null && !eventArgs.ReturnType.Equals(typeRef))
            {
                property.Type = eventArgs.ReturnType;
            }
            else
            {
                property.Type = typeRef;
            }

            property.Attributes = MemberAttributes.Final;

            CodeMethodInvokeExpression getMethod = EmitGetMethod(target);
            CodeExpression             getReturnExpression;

            property.Attributes |= AccessibilityFromGettersAndSetters(Item);
            // setup the accessibility of the navigation property setter and getter
            MemberAttributes propertyAccessibility = property.Attributes & MemberAttributes.AccessMask;

            PropertyEmitter.AddGetterSetterFixUp(Generator.FixUps, GetFullyQualifiedPropertyName(property.Name),
                                                 PropertyEmitter.GetGetterAccessibility(Item), propertyAccessibility, true);
            PropertyEmitter.AddGetterSetterFixUp(Generator.FixUps, GetFullyQualifiedPropertyName(property.Name),
                                                 PropertyEmitter.GetSetterAccessibility(Item), propertyAccessibility, false);

            if (target.RelationshipMultiplicity != RelationshipMultiplicity.Many)
            {
                // insert user-supplied Set code here, before the assignment
                //
                List <CodeStatement> additionalSetStatements = eventArgs.AdditionalSetStatements;
                if (additionalSetStatements != null && additionalSetStatements.Count > 0)
                {
                    try
                    {
                        property.SetStatements.AddRange(additionalSetStatements.ToArray());
                    }
                    catch (ArgumentNullException ex)
                    {
                        Generator.AddError(Strings.InvalidSetStatementSuppliedForProperty(Item.Name),
                                           ModelBuilderErrorCode.InvalidSetStatementSuppliedForProperty,
                                           EdmSchemaErrorSeverity.Error,
                                           ex);
                    }
                }

                CodeExpression valueRef = new CodePropertySetValueReferenceExpression();
                if (typeRef != eventArgs.ReturnType)
                {
                    // we need to cast to the actual type
                    valueRef = new CodeCastExpression(typeRef, valueRef);
                }

                if (referenceProperty)
                {
                    // get
                    //     return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<TTargetEntity>("CSpaceQualifiedRelationshipName", "TargetRoleName");
                    getReturnExpression = getMethod;

                    // set
                    // if (value != null)
                    // {
                    //    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference<TTargetEntity>"CSpaceQualifiedRelationshipName", "TargetRoleName", value);
                    // }

                    CodeMethodReferenceExpression initReferenceMethod = new CodeMethodReferenceExpression();
                    initReferenceMethod.MethodName = "InitializeRelatedReference";

                    initReferenceMethod.TypeArguments.Add(Generator.GetLeastPossibleQualifiedTypeReference(GetEntityType(target)));
                    initReferenceMethod.TargetObject = new CodePropertyReferenceExpression(
                        new CodeCastExpression(TypeReference.IEntityWithRelationshipsTypeBaseClass, ThisRef),
                        "RelationshipManager");

                    // relationships aren't backed by types so we won't map the namespace
                    // or we can't find the relationship again later
                    string cspaceNamespaceNameQualifiedRelationshipName = target.DeclaringType.FullName;

                    property.SetStatements.Add(
                        new CodeConditionStatement(
                            EmitExpressionDoesNotEqualNull(valueRef),
                            new CodeExpressionStatement(
                                new CodeMethodInvokeExpression(
                                    initReferenceMethod, new CodeExpression[] {
                        new CodePrimitiveExpression(cspaceNamespaceNameQualifiedRelationshipName), new CodePrimitiveExpression(target.Name), valueRef
                    }))));
                }
                else
                {
                    CodePropertyReferenceExpression valueProperty = new CodePropertyReferenceExpression(getMethod, ValuePropertyName);

                    // get
                    //     return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<TTargetEntity>("CSpaceQualifiedRelationshipName", "TargetRoleName").Value;
                    getReturnExpression = valueProperty;

                    // set
                    //     ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<TTargetEntity>("CSpaceQualifiedRelationshipName", "TargetRoleName").Value = value;
                    property.SetStatements.Add(
                        new CodeAssignStatement(valueProperty, valueRef));
                }
            }
            else
            {
                // get
                //     return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<TTargetEntity>("CSpaceQualifiedRelationshipName", "TargetRoleName");
                getReturnExpression = getMethod;

                // set
                // if (value != null)
                // {
                //    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection<TTargetEntity>"CSpaceQualifiedRelationshipName", "TargetRoleName", value);
                // }
                CodeExpression valueRef = new CodePropertySetValueReferenceExpression();

                CodeMethodReferenceExpression initCollectionMethod = new CodeMethodReferenceExpression();
                initCollectionMethod.MethodName = "InitializeRelatedCollection";

                initCollectionMethod.TypeArguments.Add(Generator.GetLeastPossibleQualifiedTypeReference(GetEntityType(target)));
                initCollectionMethod.TargetObject = new CodePropertyReferenceExpression(
                    new CodeCastExpression(TypeReference.IEntityWithRelationshipsTypeBaseClass, ThisRef),
                    "RelationshipManager");

                // relationships aren't backed by types so we won't map the namespace
                // or we can't find the relationship again later
                string cspaceNamespaceNameQualifiedRelationshipName = target.DeclaringType.FullName;

                property.SetStatements.Add(
                    new CodeConditionStatement(
                        EmitExpressionDoesNotEqualNull(valueRef),
                        new CodeExpressionStatement(
                            new CodeMethodInvokeExpression(
                                initCollectionMethod, new CodeExpression[] {
                    new CodePrimitiveExpression(cspaceNamespaceNameQualifiedRelationshipName), new CodePrimitiveExpression(target.Name), valueRef
                }))));
            }

            // if additional Get statements were specified by the event subscriber, insert them now
            //
            List <CodeStatement> additionalGetStatements = eventArgs.AdditionalGetStatements;

            if (additionalGetStatements != null && additionalGetStatements.Count > 0)
            {
                try
                {
                    property.GetStatements.AddRange(additionalGetStatements.ToArray());
                }
                catch (ArgumentNullException ex)
                {
                    Generator.AddError(Strings.InvalidGetStatementSuppliedForProperty(Item.Name),
                                       ModelBuilderErrorCode.InvalidGetStatementSuppliedForProperty,
                                       EdmSchemaErrorSeverity.Error,
                                       ex);
                }
            }

            property.GetStatements.Add(new CodeMethodReturnStatement(getReturnExpression));

            return(property);
        }
        /// <summary>
        /// Generate a navigation property
        /// </summary>
        /// <param name="target">the other end</param>
        /// <param name="referenceProperty">True to emit Reference navigation property</param>
        /// <returns>the generated property</returns>
        private CodeMemberProperty EmitNavigationProperty(RelationshipEndMember target)
        {
            CodeTypeReference typeRef = GetReturnType(target);

            // raise the PropertyGenerated event
            PropertyGeneratedEventArgs eventArgs = new PropertyGeneratedEventArgs(Item,
                                                                                  null, // no backing field
                                                                                  typeRef);

            this.Generator.RaisePropertyGeneratedEvent(eventArgs);

            // [System.ComponentModel.Browsable(false)]
            // public TargetType TargetName
            // public EntityReference<TargetType> TargetName
            // or
            // public EntityCollection<targetType> TargetNames
            CodeMemberProperty property = new CodeMemberProperty();

            // Only reference navigation properties are currently currently supported with XML serialization
            // and thus we should use the XmlIgnore and SoapIgnore attributes on other property types.
            AttributeEmitter.AddIgnoreAttributes(property);

            AttributeEmitter.AddBrowsableAttribute(property);

            AttributeEmitter.AddGeneratedCodeAttribute(property);

            CommentEmitter.EmitSummaryComments(Item, property.Comments);

            property.Name = Item.Name;

            if (eventArgs.ReturnType != null && !eventArgs.ReturnType.Equals(typeRef))
            {
                property.Type = eventArgs.ReturnType;
            }
            else
            {
                property.Type = typeRef;
            }

            property.Attributes = MemberAttributes.Final;

            CodeExpression getMethod = EmitGetMethod(target);
            CodeExpression getReturnExpression;

            if (target.RelationshipMultiplicity != RelationshipMultiplicity.Many)
            {
                property.Attributes |= AccessibilityFromGettersAndSetters(Item);

                // insert user-supplied Set code here, before the assignment
                //
                List <CodeStatement> additionalSetStatements = eventArgs.AdditionalSetStatements;
                if (additionalSetStatements != null && additionalSetStatements.Count > 0)
                {
                    try
                    {
                        property.SetStatements.AddRange(additionalSetStatements.ToArray());
                    }
                    catch (ArgumentNullException e)
                    {
                        Generator.AddError(Strings.InvalidSetStatementSuppliedForProperty(Item.Name),
                                           ModelBuilderErrorCode.InvalidSetStatementSuppliedForProperty,
                                           EdmSchemaErrorSeverity.Error,
                                           e);
                    }
                }

                CodeExpression valueRef = new CodePropertySetValueReferenceExpression();
                if (typeRef != eventArgs.ReturnType)
                {
                    // we need to cast to the actual type
                    valueRef = new CodeCastExpression(typeRef, valueRef);
                }


                CodeExpression valueProperty = getMethod;

                // get
                //     return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<TTargetEntity>("CSpaceQualifiedRelationshipName", "TargetRoleName").Value;
                getReturnExpression = valueProperty;

                // set
                //     ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference<TTargetEntity>("CSpaceQualifiedRelationshipName", "TargetRoleName").Value = value;
                property.SetStatements.Add(
                    new CodeAssignStatement(valueProperty, valueRef));

                // setup the accessibility of the navigation property setter and getter
                MemberAttributes propertyAccessibility = property.Attributes & MemberAttributes.AccessMask;
                PropertyEmitter.AddGetterSetterFixUp(Generator.FixUps, GetFullyQualifiedPropertyName(property.Name),
                                                     PropertyEmitter.GetGetterAccessibility(Item), propertyAccessibility, true);
                PropertyEmitter.AddGetterSetterFixUp(Generator.FixUps, GetFullyQualifiedPropertyName(property.Name),
                                                     PropertyEmitter.GetSetterAccessibility(Item), propertyAccessibility, false);

                List <CodeStatement> additionalAfterSetStatements = eventArgs.AdditionalAfterSetStatements;
                if (additionalAfterSetStatements != null && additionalAfterSetStatements.Count > 0)
                {
                    try
                    {
                        property.SetStatements.AddRange(additionalAfterSetStatements.ToArray());
                    }
                    catch (ArgumentNullException e)
                    {
                        Generator.AddError(Strings.InvalidSetStatementSuppliedForProperty(Item.Name),
                                           ModelBuilderErrorCode.InvalidSetStatementSuppliedForProperty,
                                           EdmSchemaErrorSeverity.Error,
                                           e);
                    }
                }
            }
            else
            {
                property.Attributes |= PropertyEmitter.GetGetterAccessibility(Item);
                // get
                //     return ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection<TTargetEntity>("CSpaceQualifiedRelationshipName", "TargetRoleName");
                getReturnExpression = getMethod;

                // set
                // if (value != null) ==> Only for non-binding scenario
                // {
                //    this =
                //    this.OnPropertyChanged("")
                // }

                CodeExpression valueRef = new CodePropertySetValueReferenceExpression();

                CodeStatementCollection csc = null;

                if (this.Generator.UseDataServiceCollection == true)
                {
                    csc = property.SetStatements;
                }
                else
                {
                    CodeConditionStatement ccs = new CodeConditionStatement(EmitExpressionDoesNotEqualNull(valueRef));
                    property.SetStatements.Add(ccs);

                    csc = ccs.TrueStatements;
                }

                csc.Add(new CodeAssignStatement(getMethod, valueRef));

                if (eventArgs.AdditionalAfterSetStatements != null)
                {
                    try
                    {
                        foreach (CodeStatement s in eventArgs.AdditionalAfterSetStatements)
                        {
                            csc.Add(s);
                        }
                    }
                    catch (ArgumentNullException e)
                    {
                        Generator.AddError(Strings.InvalidSetStatementSuppliedForProperty(Item.Name),
                                           ModelBuilderErrorCode.InvalidSetStatementSuppliedForProperty,
                                           EdmSchemaErrorSeverity.Error,
                                           e);
                    }
                }
            }

            // if additional Get statements were specified by the event subscriber, insert them now
            //
            List <CodeStatement> additionalGetStatements = eventArgs.AdditionalGetStatements;

            if (additionalGetStatements != null && additionalGetStatements.Count > 0)
            {
                try
                {
                    property.GetStatements.AddRange(additionalGetStatements.ToArray());
                }
                catch (ArgumentNullException ex)
                {
                    Generator.AddError(Strings.InvalidGetStatementSuppliedForProperty(Item.Name),
                                       ModelBuilderErrorCode.InvalidGetStatementSuppliedForProperty,
                                       EdmSchemaErrorSeverity.Error,
                                       ex);
                }
            }

            property.GetStatements.Add(new CodeMethodReturnStatement(getReturnExpression));

            return(property);
        }
Example #18
0
        private CodeMemberProperty CreateEntitySetProperty(EntitySet set)
        {
            Debug.Assert(set != null, "Property is Null");

            // trying to get
            //
            // [System.ComponentModel.Browsable(false)]
            // public ObjectQuery<Customer> Customers
            // {
            //      get
            //      {
            //          if ((this._Customers == null))
            //          {
            //              this._Customers = base.CreateQuery<Customer>("[Customers]");
            //          }
            //          return this._Customers;
            //      }
            // }
            CodeMemberProperty codeProperty = new CodeMemberProperty();

            codeProperty.Attributes = MemberAttributes.Final | GetEntitySetPropertyAccessibility(set);
            codeProperty.Name       = set.Name;
            codeProperty.HasGet     = true;
            codeProperty.HasSet     = false;

            // SQLBUDT 598300: property to get query hides a property on base Context?
            if (null != TypeReference.ObjectContextBaseClassType.GetProperty(set.Name))
            {
                codeProperty.Attributes |= MemberAttributes.New;
            }

            AttributeEmitter.AddBrowsableAttribute(codeProperty);
            AttributeEmitter.AddGeneratedCodeAttribute(codeProperty);

            CodeTypeReference genericParameter = Generator.GetLeastPossibleQualifiedTypeReference(set.ElementType);

            codeProperty.Type = TypeReference.AdoFrameworkGenericClass("DataServiceQuery", genericParameter);
            string fieldName = Utils.FieldNameFromPropName(set.Name);

            // raise the PropertyGenerated event before proceeding further
            PropertyGeneratedEventArgs eventArgs = new PropertyGeneratedEventArgs(set, fieldName, codeProperty.Type);

            Generator.RaisePropertyGeneratedEvent(eventArgs);

            if (eventArgs.ReturnType == null || !eventArgs.ReturnType.Equals(codeProperty.Type))
            {
                throw EDesignUtil.InvalidOperation(Strings.CannotChangePropertyReturnType(set.Name, Item.Name));
            }

            List <CodeAttributeDeclaration> additionalAttributes = eventArgs.AdditionalAttributes;

            if (additionalAttributes != null && additionalAttributes.Count > 0)
            {
                try
                {
                    codeProperty.CustomAttributes.AddRange(additionalAttributes.ToArray());
                }
                catch (ArgumentNullException e)
                {
                    Generator.AddError(Strings.InvalidAttributeSuppliedForProperty(Item.Name),
                                       ModelBuilderErrorCode.InvalidAttributeSuppliedForProperty,
                                       EdmSchemaErrorSeverity.Error,
                                       e);
                }
            }

            // we need to insert user-specified code before other/existing code, including
            // the return statement
            List <CodeStatement> additionalGetStatements = eventArgs.AdditionalGetStatements;

            if (additionalGetStatements != null && additionalGetStatements.Count > 0)
            {
                try
                {
                    codeProperty.GetStatements.AddRange(additionalGetStatements.ToArray());
                }
                catch (ArgumentNullException e)
                {
                    Generator.AddError(Strings.InvalidGetStatementSuppliedForProperty(Item.Name),
                                       ModelBuilderErrorCode.InvalidGetStatementSuppliedForProperty,
                                       EdmSchemaErrorSeverity.Error,
                                       e);
                }
            }

            codeProperty.GetStatements.Add(
                new CodeConditionStatement(
                    EmitExpressionEqualsNull(new CodeFieldReferenceExpression(ThisRef, fieldName)),
                    new CodeAssignStatement(
                        new CodeFieldReferenceExpression(ThisRef, fieldName),
                        new CodeMethodInvokeExpression(
                            new CodeMethodReferenceExpression(
                                new CodeBaseReferenceExpression(),
                                "CreateQuery",
                                new CodeTypeReference[] { genericParameter }
                                ),
                            new CodePrimitiveExpression(set.Name)
                            )
                        )
                    )
                );

            codeProperty.GetStatements.Add(
                new CodeMethodReturnStatement(
                    new CodeFieldReferenceExpression(
                        ThisRef,
                        fieldName
                        )
                    )
                );

            // property summary
            CommentEmitter.EmitSummaryComments(set, codeProperty.Comments);

            return(codeProperty);
        }