EntityContainerRelationshipSet.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataEntity / System / Data / EntityModel / SchemaObjectModel / EntityContainerRelationshipSet.cs / 3 / EntityContainerRelationshipSet.cs

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

using System; 
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics; 
using System.Xml;
using System.Data; 
using System.Data.Metadata.Edm; 
using System.Data.Entity;
 
namespace System.Data.EntityModel.SchemaObjectModel
{
    /// 
    /// Represents an RelationshipSet element. 
    /// 
    internal abstract class EntityContainerRelationshipSet : SchemaElement 
    { 

        private IRelationship _relationship; 
        string _unresolvedRelationshipTypeName;


        ///  
        /// Constructs an EntityContainerRelationshipSet
        ///  
        /// Reference to the schema element. 
        public EntityContainerRelationshipSet( EntityContainer parentElement )
            : base( parentElement ) 
        {
        }

        internal IRelationship Relationship 
        {
            get 
            { 
                return _relationship;
            } 
            set
            {
                Debug.Assert(value != null, "relationship can never be set to null");
                _relationship = value; 
            }
        } 
 
        protected abstract bool HasEnd( string role );
        protected abstract void AddEnd( IRelationshipEnd relationshipEnd, EntityContainerEntitySet entitySet ); 
        internal abstract IEnumerable Ends { get; }

        /// 
        /// The method that is called when an Association attribute is encountered. 
        /// 
        /// An XmlReader positioned at the Association attribute. 
        protected void HandleRelationshipTypeNameAttribute( XmlReader reader ) 
        {
            Debug.Assert( reader != null ); 
            ReturnValue value = HandleDottedNameAttribute( reader, _unresolvedRelationshipTypeName, Strings.PropertyTypeAlreadyDefined );
            if ( value.Succeeded )
            {
                _unresolvedRelationshipTypeName = value.Value; 
            }
        } 
 

        ///  
        /// Used during the resolve phase to resolve the type name to the object that represents that type
        /// 
        internal override void ResolveTopLevelNames()
        { 
            base.ResolveTopLevelNames();
 
            if ( _relationship == null ) 
            {
                SchemaType element; 
                if ( !Schema.ResolveTypeName( this, _unresolvedRelationshipTypeName, out element ) )
                {
                    return;
                } 

                _relationship = element as IRelationship; 
                if ( _relationship == null ) 
                {
                    AddError( ErrorCode.InvalidPropertyType, EdmSchemaErrorSeverity.Error, 
                        System.Data.Entity.Strings.InvalidRelationshipSetType(element.Name ) );
                    return;
                }
            } 

            foreach ( EntityContainerRelationshipSetEnd end in Ends ) 
            { 
                end.ResolveTopLevelNames();
            } 
        }

        internal override void ResolveSecondLevelNames()
        { 
            base.ResolveSecondLevelNames();
            foreach (EntityContainerRelationshipSetEnd end in Ends) 
            { 
                end.ResolveSecondLevelNames();
            } 
        }

        /// 
        /// Do all validation for this element here, and delegate to all sub elements 
        /// 
        internal override void Validate() 
        { 
            base.Validate();
 
            InferEnds();

            // check out the ends
            foreach ( EntityContainerRelationshipSetEnd end in Ends ) 
            {
                end.Validate(); 
            } 

 
            // Enabling Association between subtypes in case of Referential Constraints, since
            // CSD is blocked on this. We need to make a long term call about whether we should
            // really allow this. Bug #520216
            //foreach (ReferentialConstraint constraint in Relationship.Constraints) 
            //{
            //    IRelationshipEnd dependentEnd = constraint.DependentRole.End; 
            //    EntityContainerRelationshipSetEnd setEnd = GetEnd(dependentEnd.Name); 
            //    Debug.Assert(setEnd != null);
            //    //Make sure that the EntityType of the dependant role in a referential constraint 
            //    //covers the whole EntitySet( i.e. not  a subtype of the EntitySet's type).
            //    if (!setEnd.EntitySet.EntityType.IsOfType(constraint.DependentRole.End.Type))
            //    {
            //        AddError(ErrorCode.InvalidDependentRoleType, EdmSchemaErrorSeverity.Error, 
            //            System.Data.Entity.Strings.InvalidDependentRoleType(dependentEnd.Type.FQName, dependentEnd.Name,
            //                                dependentEnd.Parent.FQName, setEnd.EntitySet.Name, setEnd.ParentElement.Name)); 
            //    } 
            //}
 
            // Validate Number of ends is correct
            //    What we know:
            //      No ends are missing, becuase we infered all missing ends
            //      No extra ends are there because the names have been matched, and an extra name will have caused an error 
            //
            //    looks like no count validation needs to be done 
 
        }
 
        /// 
        /// Adds any ends that need to be infered
        /// 
        private void InferEnds() 
        {
            Debug.Assert( Relationship != null ); 
 
            foreach ( IRelationshipEnd relationshipEnd in Relationship.Ends )
            { 
                if ( ! HasEnd( relationshipEnd.Name ) )
                {
                    EntityContainerEntitySet entitySet = InferEntitySet(relationshipEnd);
                    if (entitySet != null) 
                    {
                        // we don't have this end, we need to add it 
                        AddEnd(relationshipEnd, entitySet); 
                    }
                } 
            }
        }

 
        /// 
        /// For the given relationship end, find the EntityContainer Property that will work for the extent 
        ///  
        /// The relationship end of the RelationshipSet that needs and extent
        /// Null is none could be found, or the EntityContainerProperty that is the valid extent 
        private EntityContainerEntitySet InferEntitySet( IRelationshipEnd relationshipEnd )
        {
            Debug.Assert(relationshipEnd != null, "relationshipEnd parameter is null");
 
            List possibleExtents = new List();
            foreach ( EntityContainerEntitySet set in ParentElement.EntitySets ) 
            { 
                if ( relationshipEnd.Type.IsOfType( set.EntityType ) )
                { 
                    possibleExtents.Add( set );
                }
            }
 
            if ( possibleExtents.Count == 1 )
            { 
                return possibleExtents[0]; 
            }
            else if ( possibleExtents.Count == 0 ) 
            {
                // no matchs
                AddError( ErrorCode.MissingExtentEntityContainerEnd, EdmSchemaErrorSeverity.Error,
                    System.Data.Entity.Strings.MissingEntityContainerEnd(relationshipEnd.Name, FQName ) ); 
            }
            else 
            { 
                // abmigous
                AddError( ErrorCode.AmbiguousEntityContainerEnd, EdmSchemaErrorSeverity.Error, 
                    System.Data.Entity.Strings.AmbiguousEntityContainerEnd(relationshipEnd.Name, FQName ) );
            }

            return null; 
        }
 
 
        /// 
        /// The parent element as an EntityContainer 
        /// 
        internal new EntityContainer ParentElement
        {
            get 
            {
                return (EntityContainer)( base.ParentElement ); 
            } 
        }
    } 
}

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

using System; 
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics; 
using System.Xml;
using System.Data; 
using System.Data.Metadata.Edm; 
using System.Data.Entity;
 
namespace System.Data.EntityModel.SchemaObjectModel
{
    /// 
    /// Represents an RelationshipSet element. 
    /// 
    internal abstract class EntityContainerRelationshipSet : SchemaElement 
    { 

        private IRelationship _relationship; 
        string _unresolvedRelationshipTypeName;


        ///  
        /// Constructs an EntityContainerRelationshipSet
        ///  
        /// Reference to the schema element. 
        public EntityContainerRelationshipSet( EntityContainer parentElement )
            : base( parentElement ) 
        {
        }

        internal IRelationship Relationship 
        {
            get 
            { 
                return _relationship;
            } 
            set
            {
                Debug.Assert(value != null, "relationship can never be set to null");
                _relationship = value; 
            }
        } 
 
        protected abstract bool HasEnd( string role );
        protected abstract void AddEnd( IRelationshipEnd relationshipEnd, EntityContainerEntitySet entitySet ); 
        internal abstract IEnumerable Ends { get; }

        /// 
        /// The method that is called when an Association attribute is encountered. 
        /// 
        /// An XmlReader positioned at the Association attribute. 
        protected void HandleRelationshipTypeNameAttribute( XmlReader reader ) 
        {
            Debug.Assert( reader != null ); 
            ReturnValue value = HandleDottedNameAttribute( reader, _unresolvedRelationshipTypeName, Strings.PropertyTypeAlreadyDefined );
            if ( value.Succeeded )
            {
                _unresolvedRelationshipTypeName = value.Value; 
            }
        } 
 

        ///  
        /// Used during the resolve phase to resolve the type name to the object that represents that type
        /// 
        internal override void ResolveTopLevelNames()
        { 
            base.ResolveTopLevelNames();
 
            if ( _relationship == null ) 
            {
                SchemaType element; 
                if ( !Schema.ResolveTypeName( this, _unresolvedRelationshipTypeName, out element ) )
                {
                    return;
                } 

                _relationship = element as IRelationship; 
                if ( _relationship == null ) 
                {
                    AddError( ErrorCode.InvalidPropertyType, EdmSchemaErrorSeverity.Error, 
                        System.Data.Entity.Strings.InvalidRelationshipSetType(element.Name ) );
                    return;
                }
            } 

            foreach ( EntityContainerRelationshipSetEnd end in Ends ) 
            { 
                end.ResolveTopLevelNames();
            } 
        }

        internal override void ResolveSecondLevelNames()
        { 
            base.ResolveSecondLevelNames();
            foreach (EntityContainerRelationshipSetEnd end in Ends) 
            { 
                end.ResolveSecondLevelNames();
            } 
        }

        /// 
        /// Do all validation for this element here, and delegate to all sub elements 
        /// 
        internal override void Validate() 
        { 
            base.Validate();
 
            InferEnds();

            // check out the ends
            foreach ( EntityContainerRelationshipSetEnd end in Ends ) 
            {
                end.Validate(); 
            } 

 
            // Enabling Association between subtypes in case of Referential Constraints, since
            // CSD is blocked on this. We need to make a long term call about whether we should
            // really allow this. Bug #520216
            //foreach (ReferentialConstraint constraint in Relationship.Constraints) 
            //{
            //    IRelationshipEnd dependentEnd = constraint.DependentRole.End; 
            //    EntityContainerRelationshipSetEnd setEnd = GetEnd(dependentEnd.Name); 
            //    Debug.Assert(setEnd != null);
            //    //Make sure that the EntityType of the dependant role in a referential constraint 
            //    //covers the whole EntitySet( i.e. not  a subtype of the EntitySet's type).
            //    if (!setEnd.EntitySet.EntityType.IsOfType(constraint.DependentRole.End.Type))
            //    {
            //        AddError(ErrorCode.InvalidDependentRoleType, EdmSchemaErrorSeverity.Error, 
            //            System.Data.Entity.Strings.InvalidDependentRoleType(dependentEnd.Type.FQName, dependentEnd.Name,
            //                                dependentEnd.Parent.FQName, setEnd.EntitySet.Name, setEnd.ParentElement.Name)); 
            //    } 
            //}
 
            // Validate Number of ends is correct
            //    What we know:
            //      No ends are missing, becuase we infered all missing ends
            //      No extra ends are there because the names have been matched, and an extra name will have caused an error 
            //
            //    looks like no count validation needs to be done 
 
        }
 
        /// 
        /// Adds any ends that need to be infered
        /// 
        private void InferEnds() 
        {
            Debug.Assert( Relationship != null ); 
 
            foreach ( IRelationshipEnd relationshipEnd in Relationship.Ends )
            { 
                if ( ! HasEnd( relationshipEnd.Name ) )
                {
                    EntityContainerEntitySet entitySet = InferEntitySet(relationshipEnd);
                    if (entitySet != null) 
                    {
                        // we don't have this end, we need to add it 
                        AddEnd(relationshipEnd, entitySet); 
                    }
                } 
            }
        }

 
        /// 
        /// For the given relationship end, find the EntityContainer Property that will work for the extent 
        ///  
        /// The relationship end of the RelationshipSet that needs and extent
        /// Null is none could be found, or the EntityContainerProperty that is the valid extent 
        private EntityContainerEntitySet InferEntitySet( IRelationshipEnd relationshipEnd )
        {
            Debug.Assert(relationshipEnd != null, "relationshipEnd parameter is null");
 
            List possibleExtents = new List();
            foreach ( EntityContainerEntitySet set in ParentElement.EntitySets ) 
            { 
                if ( relationshipEnd.Type.IsOfType( set.EntityType ) )
                { 
                    possibleExtents.Add( set );
                }
            }
 
            if ( possibleExtents.Count == 1 )
            { 
                return possibleExtents[0]; 
            }
            else if ( possibleExtents.Count == 0 ) 
            {
                // no matchs
                AddError( ErrorCode.MissingExtentEntityContainerEnd, EdmSchemaErrorSeverity.Error,
                    System.Data.Entity.Strings.MissingEntityContainerEnd(relationshipEnd.Name, FQName ) ); 
            }
            else 
            { 
                // abmigous
                AddError( ErrorCode.AmbiguousEntityContainerEnd, EdmSchemaErrorSeverity.Error, 
                    System.Data.Entity.Strings.AmbiguousEntityContainerEnd(relationshipEnd.Name, FQName ) );
            }

            return null; 
        }
 
 
        /// 
        /// The parent element as an EntityContainer 
        /// 
        internal new EntityContainer ParentElement
        {
            get 
            {
                return (EntityContainer)( base.ParentElement ); 
            } 
        }
    } 
}

// 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