NavigationPropertyEmitter.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntityDesign / Design / System / Data / EntityModel / Emitters / NavigationPropertyEmitter.cs / 1305376 / NavigationPropertyEmitter.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner       [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System; 
using System.CodeDom;
using System.Data;
using System.Collections.Generic;
using System.Data.Entity.Design; 
using Som=System.Data.EntityModel.SchemaObjectModel;
using System.Data.Metadata.Edm; 
using System.Diagnostics; 
using System.Data.Entity.Design.SsdlGenerator;
using System.Data.Entity.Design.Common; 


namespace System.Data.EntityModel.Emitters
{ 
    /// 
    /// Summary description for NavigationPropertyEmitter. 
    ///  
    internal sealed class NavigationPropertyEmitter : PropertyEmitterBase
    { 
        private const string ValuePropertyName = "Value";

        /// 
        /// 
        /// 
        ///  
        ///  
        public NavigationPropertyEmitter(ClientApiGenerator generator, NavigationProperty navigationProperty, bool declaringTypeUsesStandardBaseType)
            : base(generator, navigationProperty, declaringTypeUsesStandardBaseType) 
        {
        }

        ///  
        /// Generate the navigation property
        ///  
        /// The type to add the property to. 
        protected override void EmitProperty(CodeTypeDeclaration typeDecl)
        { 
            EmitNavigationProperty(typeDecl);
        }

        ///  
        /// Generate the navigation property specified
        ///  
        /// The type to add the property to. 
        private void EmitNavigationProperty( CodeTypeDeclaration typeDecl )
        { 
            // create a regular property
            CodeMemberProperty property = EmitNavigationProperty(Item.ToEndMember, false);
            typeDecl.Members.Add(property);
 
            if (Item.ToEndMember.RelationshipMultiplicity != RelationshipMultiplicity.Many)
            { 
                // create a ref property 
                property = EmitNavigationProperty(Item.ToEndMember, true);
                typeDecl.Members.Add(property); 

            }
        }
 
        /// 
        /// Generate a navigation property 
        ///  
        /// the other end
        /// True to emit Reference navigation property 
        /// the generated property
        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 TargetName
            // or 
            // public EntityCollection 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 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("CSpaceQualifiedRelationshipName", "TargetRoleName");
                    getReturnExpression = getMethod;
 
                    // set
                    // if (value != null) 
                    // { 
                    //    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference"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("CSpaceQualifiedRelationshipName", "TargetRoleName").Value; 
                    getReturnExpression = valueProperty;

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

                // set 
                // if (value != null) 
                // {
                //    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection"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 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;
        }

        internal static bool IsNameAlreadyAMemberName(StructuralType type, string generatedPropertyName, StringComparison comparison) 
        {
            foreach (EdmMember member in type.Members) 
            { 
                if (member.DeclaringType == type &&
                    member.Name.Equals(generatedPropertyName, comparison)) 
                {
                    return true;
                }
            } 

            return false; 
        } 

        private string GetFullyQualifiedPropertyName(string propertyName) 
        {
            return Item.DeclaringType.FullName + "." + propertyName;
        }
 
        /// 
        /// Gives the SchemaElement back cast to the most 
        /// appropriate type 
        /// 
        private new NavigationProperty Item 
        {
            get
            {
                return base.Item as NavigationProperty; 
            }
        } 
 
        /// 
        /// Get the return type for the get method, given the target end 
        /// 
        /// 
        /// true if the is the return type for a reference property
        /// the return type for a target 
        private CodeTypeReference GetReturnType(RelationshipEndMember target, bool referenceMethod)
        { 
            CodeTypeReference returnType = Generator.GetLeastPossibleQualifiedTypeReference(GetEntityType(target)); 
            if (referenceMethod)
            { 
                returnType = TypeReference.AdoFrameworkGenericDataClass("EntityReference", returnType);
            }
            else if (target.RelationshipMultiplicity == RelationshipMultiplicity.Many)
            { 
                returnType = TypeReference.AdoFrameworkGenericDataClass("EntityCollection", returnType);
            } 
 
            return returnType;
        } 


        private static EntityTypeBase GetEntityType(RelationshipEndMember endMember)
        { 
            Debug.Assert(endMember.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.RefType, "not a reference type");
            EntityTypeBase type = ((RefType)endMember.TypeUsage.EdmType).ElementType; 
            return type; 
        }
 
        /// 
        /// Emit the GetRelatedCollection or GetRelatedReference methods
        /// 
        /// Target end of the relationship 
        /// Expression to invoke the appropriate method
        private CodeMethodInvokeExpression EmitGetMethod(RelationshipEndMember target) 
        { 
            // ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("CSpaceQualifiedRelationshipName", "TargetRoleName");
            // or 
            // ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection("CSpaceQualifiedRelationshipName", "TargetRoleName");

            CodeMethodReferenceExpression getMethod = new CodeMethodReferenceExpression();
            if (target.RelationshipMultiplicity != RelationshipMultiplicity.Many) 
                getMethod.MethodName = "GetRelatedReference";
            else 
                getMethod.MethodName = "GetRelatedCollection"; 

            getMethod.TypeArguments.Add(Generator.GetLeastPossibleQualifiedTypeReference(GetEntityType(target))); 
            getMethod.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; 
            return new CodeMethodInvokeExpression(
                getMethod, new CodeExpression[] { new CodePrimitiveExpression(cspaceNamespaceNameQualifiedRelationshipName), new CodePrimitiveExpression(target.Name)}); 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner       [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

using System; 
using System.CodeDom;
using System.Data;
using System.Collections.Generic;
using System.Data.Entity.Design; 
using Som=System.Data.EntityModel.SchemaObjectModel;
using System.Data.Metadata.Edm; 
using System.Diagnostics; 
using System.Data.Entity.Design.SsdlGenerator;
using System.Data.Entity.Design.Common; 


namespace System.Data.EntityModel.Emitters
{ 
    /// 
    /// Summary description for NavigationPropertyEmitter. 
    ///  
    internal sealed class NavigationPropertyEmitter : PropertyEmitterBase
    { 
        private const string ValuePropertyName = "Value";

        /// 
        /// 
        /// 
        ///  
        ///  
        public NavigationPropertyEmitter(ClientApiGenerator generator, NavigationProperty navigationProperty, bool declaringTypeUsesStandardBaseType)
            : base(generator, navigationProperty, declaringTypeUsesStandardBaseType) 
        {
        }

        ///  
        /// Generate the navigation property
        ///  
        /// The type to add the property to. 
        protected override void EmitProperty(CodeTypeDeclaration typeDecl)
        { 
            EmitNavigationProperty(typeDecl);
        }

        ///  
        /// Generate the navigation property specified
        ///  
        /// The type to add the property to. 
        private void EmitNavigationProperty( CodeTypeDeclaration typeDecl )
        { 
            // create a regular property
            CodeMemberProperty property = EmitNavigationProperty(Item.ToEndMember, false);
            typeDecl.Members.Add(property);
 
            if (Item.ToEndMember.RelationshipMultiplicity != RelationshipMultiplicity.Many)
            { 
                // create a ref property 
                property = EmitNavigationProperty(Item.ToEndMember, true);
                typeDecl.Members.Add(property); 

            }
        }
 
        /// 
        /// Generate a navigation property 
        ///  
        /// the other end
        /// True to emit Reference navigation property 
        /// the generated property
        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 TargetName
            // or 
            // public EntityCollection 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 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("CSpaceQualifiedRelationshipName", "TargetRoleName");
                    getReturnExpression = getMethod;
 
                    // set
                    // if (value != null) 
                    // { 
                    //    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedReference"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("CSpaceQualifiedRelationshipName", "TargetRoleName").Value; 
                    getReturnExpression = valueProperty;

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

                // set 
                // if (value != null) 
                // {
                //    ((IEntityWithRelationships)this).RelationshipManager.InitializeRelatedCollection"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 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;
        }

        internal static bool IsNameAlreadyAMemberName(StructuralType type, string generatedPropertyName, StringComparison comparison) 
        {
            foreach (EdmMember member in type.Members) 
            { 
                if (member.DeclaringType == type &&
                    member.Name.Equals(generatedPropertyName, comparison)) 
                {
                    return true;
                }
            } 

            return false; 
        } 

        private string GetFullyQualifiedPropertyName(string propertyName) 
        {
            return Item.DeclaringType.FullName + "." + propertyName;
        }
 
        /// 
        /// Gives the SchemaElement back cast to the most 
        /// appropriate type 
        /// 
        private new NavigationProperty Item 
        {
            get
            {
                return base.Item as NavigationProperty; 
            }
        } 
 
        /// 
        /// Get the return type for the get method, given the target end 
        /// 
        /// 
        /// true if the is the return type for a reference property
        /// the return type for a target 
        private CodeTypeReference GetReturnType(RelationshipEndMember target, bool referenceMethod)
        { 
            CodeTypeReference returnType = Generator.GetLeastPossibleQualifiedTypeReference(GetEntityType(target)); 
            if (referenceMethod)
            { 
                returnType = TypeReference.AdoFrameworkGenericDataClass("EntityReference", returnType);
            }
            else if (target.RelationshipMultiplicity == RelationshipMultiplicity.Many)
            { 
                returnType = TypeReference.AdoFrameworkGenericDataClass("EntityCollection", returnType);
            } 
 
            return returnType;
        } 


        private static EntityTypeBase GetEntityType(RelationshipEndMember endMember)
        { 
            Debug.Assert(endMember.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.RefType, "not a reference type");
            EntityTypeBase type = ((RefType)endMember.TypeUsage.EdmType).ElementType; 
            return type; 
        }
 
        /// 
        /// Emit the GetRelatedCollection or GetRelatedReference methods
        /// 
        /// Target end of the relationship 
        /// Expression to invoke the appropriate method
        private CodeMethodInvokeExpression EmitGetMethod(RelationshipEndMember target) 
        { 
            // ((IEntityWithRelationships)this).RelationshipManager.GetRelatedReference("CSpaceQualifiedRelationshipName", "TargetRoleName");
            // or 
            // ((IEntityWithRelationships)this).RelationshipManager.GetRelatedCollection("CSpaceQualifiedRelationshipName", "TargetRoleName");

            CodeMethodReferenceExpression getMethod = new CodeMethodReferenceExpression();
            if (target.RelationshipMultiplicity != RelationshipMultiplicity.Many) 
                getMethod.MethodName = "GetRelatedReference";
            else 
                getMethod.MethodName = "GetRelatedCollection"; 

            getMethod.TypeArguments.Add(Generator.GetLeastPossibleQualifiedTypeReference(GetEntityType(target))); 
            getMethod.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; 
            return new CodeMethodInvokeExpression(
                getMethod, new CodeExpression[] { new CodePrimitiveExpression(cspaceNamespaceNameQualifiedRelationshipName), new CodePrimitiveExpression(target.Name)}); 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK