metadatamappinghashervisitor.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 / DataEntity / System / Data / Mapping / metadatamappinghashervisitor.cs / 1508357 / metadatamappinghashervisitor.cs

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

using System; 
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Metadata.Edm; 
using System.Data.Common;
using System.Data.Common.Utils; 
using System.Data.Mapping; 
using System.Diagnostics;
using System.Globalization; 


namespace System.Data.Mapping
{ 
    internal partial class MetadataMappingHasherVisitor : BaseMetadataMappingVisitor
    { 
        private CompressingHashBuilder m_hashSourceBuilder; 
        private Dictionary m_itemsAlreadySeen = new Dictionary();
        private int m_instanceNumber = 0; 
        private EdmItemCollection m_EdmItemCollection;
        private double m_EdmVersion;
        private double m_MappingVersion;
 
        private MetadataMappingHasherVisitor(double mappingVersion)
        { 
            m_MappingVersion = mappingVersion; 
            this.m_hashSourceBuilder = new CompressingHashBuilder(MetadataHelper.CreateMetadataHashAlgorithm(m_MappingVersion));
        } 

        #region visitor method
        protected override void Visit(StorageEntityContainerMapping storageEntityContainerMapping)
        { 
            Debug.Assert(storageEntityContainerMapping != null, "storageEntityContainerMapping cannot be null!");
 
            // at the entry point of visitor, we setup the versions 
            Debug.Assert(m_MappingVersion == storageEntityContainerMapping.StorageMappingItemCollection.MappingVersion, "the original version and the mapping collection version are not the same");
            this.m_MappingVersion = storageEntityContainerMapping.StorageMappingItemCollection.MappingVersion; 
            this.m_EdmVersion = storageEntityContainerMapping.StorageMappingItemCollection.EdmItemCollection.EdmVersion;

            this.m_EdmItemCollection = storageEntityContainerMapping.StorageMappingItemCollection.EdmItemCollection;
 
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(storageEntityContainerMapping, out index)) 
            { 
                // if this has been add to the seen list, then just
                return; 
            }
            if (this.m_itemsAlreadySeen.Count > 1)
            {
 
                // this means user try another visit over SECM, this is allowed but all the previous visit all lost due to clean
                // user can visit different SECM objects by using the same visitor to load the SECM object 
                this.Clean(); 
                Visit(storageEntityContainerMapping);
                return; 
            }

            this.AddObjectStartDumpToHashBuilder(storageEntityContainerMapping, index);
 
            #region Inner data visit
 
            this.AddObjectContentToHashBuilder(storageEntityContainerMapping.Identity); 

            this.AddV2ObjectContentToHashBuilder(storageEntityContainerMapping.GenerateUpdateViews, this.m_MappingVersion); 

            base.Visit(storageEntityContainerMapping);

            #endregion 

            this.AddObjectEndDumpToHashBuilder(); 
        } 

        protected override void Visit(EntityContainer entityContainer) 
        {
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(entityContainer, out index))
            { 
                return;
            } 
 
            this.AddObjectStartDumpToHashBuilder(entityContainer, index);
 
            #region Inner data visit

            this.AddObjectContentToHashBuilder(entityContainer.Identity);
            // Name is covered by Identity 

            base.Visit(entityContainer); 
 
            #endregion
 
            this.AddObjectEndDumpToHashBuilder();
        }

        protected override void Visit(StorageSetMapping storageSetMapping) 
        {
            int index; 
            if (!this.AddObjectToSeenListAndHashBuilder(storageSetMapping, out index)) 
            {
                return; 
            }

            this.AddObjectStartDumpToHashBuilder(storageSetMapping, index);
 
            #region Inner data visit
            base.Visit(storageSetMapping); 
            #endregion 

            this.AddObjectEndDumpToHashBuilder(); 
        }

        protected override void Visit(StorageTypeMapping storageTypeMapping)
        { 
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(storageTypeMapping, out index)) 
            { 
                return;
            } 

            this.AddObjectStartDumpToHashBuilder(storageTypeMapping, index);

            #region Inner data visit 

            base.Visit(storageTypeMapping); 
 
            #endregion
 
            this.AddObjectEndDumpToHashBuilder();
        }

        protected override void Visit(StorageMappingFragment storageMappingFragment) 
        {
            int index; 
            if (!this.AddObjectToSeenListAndHashBuilder(storageMappingFragment, out index)) 
            {
                return; 
            }

            this.AddObjectStartDumpToHashBuilder(storageMappingFragment, index);
 
            #region Inner data visit
 
            this.AddV2ObjectContentToHashBuilder(storageMappingFragment.IsSQueryDistinct, this.m_MappingVersion); 

            base.Visit(storageMappingFragment); 

            #endregion

            this.AddObjectEndDumpToHashBuilder(); 
        }
 
        protected override void Visit(StoragePropertyMapping storagePropertyMapping) 
        {
            base.Visit(storagePropertyMapping); 
        }

        protected override void Visit(StorageComplexPropertyMapping storageComplexPropertyMapping)
        { 
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(storageComplexPropertyMapping, out index)) 
            { 
                return;
            } 

            this.AddObjectStartDumpToHashBuilder(storageComplexPropertyMapping, index);

            #region Inner data visit 

            base.Visit(storageComplexPropertyMapping); 
 
            #endregion
 
            this.AddObjectEndDumpToHashBuilder();
        }
        protected override void Visit(StorageComplexTypeMapping storageComplexTypeMapping)
        { 
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(storageComplexTypeMapping, out index)) 
            { 
                return;
            } 

            this.AddObjectStartDumpToHashBuilder(storageComplexTypeMapping, index);

            #region Inner data visit 

            base.Visit(storageComplexTypeMapping); 
 
            #endregion
 
            this.AddObjectEndDumpToHashBuilder();
        }

        protected override void Visit(StorageConditionPropertyMapping storageConditionPropertyMapping) 
        {
            int index; 
            if (!this.AddObjectToSeenListAndHashBuilder(storageConditionPropertyMapping, out index)) 
            {
                return; 
            }

            this.AddObjectStartDumpToHashBuilder(storageConditionPropertyMapping, index);
 
            #region Inner data visit
            this.AddObjectContentToHashBuilder(storageConditionPropertyMapping.IsNull); 
            this.AddObjectContentToHashBuilder(storageConditionPropertyMapping.Value); 

            base.Visit(storageConditionPropertyMapping); 

            #endregion

            this.AddObjectEndDumpToHashBuilder(); 
        }
 
        protected override void Visit(StorageScalarPropertyMapping storageScalarPropertyMapping) 
        {
            int index; 
            if (!this.AddObjectToSeenListAndHashBuilder(storageScalarPropertyMapping, out index))
            {
                return;
            } 

            this.AddObjectStartDumpToHashBuilder(storageScalarPropertyMapping, index); 
 
            #region Inner data visit
 
            base.Visit(storageScalarPropertyMapping);

            #endregion
 
            this.AddObjectEndDumpToHashBuilder();
        } 
 
        protected override void Visit(EntitySetBase entitySetBase)
        { 
            base.Visit(entitySetBase);
        }

        protected override void Visit(EntitySet entitySet) 
        {
            int index; 
            if (!this.AddObjectToSeenListAndHashBuilder(entitySet, out index)) 
            {
                return; 
            }
            #region Inner data visit

            this.AddObjectStartDumpToHashBuilder(entitySet, index); 
            this.AddObjectContentToHashBuilder(entitySet.Name);
            this.AddObjectContentToHashBuilder(entitySet.Schema); 
            this.AddObjectContentToHashBuilder(entitySet.Table); 

            base.Visit(entitySet); 

            foreach (var entityType in MetadataHelper.GetTypeAndSubtypesOf(entitySet.ElementType, this.m_EdmItemCollection, false).Where(type => type != entitySet.ElementType))
            {
                this.Visit(entityType); 
            }
 
            #endregion 

            this.AddObjectEndDumpToHashBuilder(); 
        }

        protected override void Visit(AssociationSet associationSet)
        { 
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(associationSet, out index)) 
            { 
                return;
            } 

            this.AddObjectStartDumpToHashBuilder(associationSet, index);

            #region Inner data visit 
            this.AddObjectContentToHashBuilder(associationSet.CachedProviderSql);
            // Name is coverd by Identity 
            this.AddObjectContentToHashBuilder(associationSet.Identity); 
            this.AddObjectContentToHashBuilder(associationSet.Schema);
            this.AddObjectContentToHashBuilder(associationSet.Table); 

            base.Visit(associationSet);

            #endregion 

            this.AddObjectEndDumpToHashBuilder(); 
        } 

        protected override void Visit(EntityType entityType) 
        {
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(entityType, out index))
            { 
                return;
            } 
 
            this.AddObjectStartDumpToHashBuilder(entityType, index);
 
            #region Inner data visit
            this.AddObjectContentToHashBuilder(entityType.Abstract);
            this.AddObjectContentToHashBuilder(entityType.Identity);
            // FullName, Namespace and Name are all covered by Identity 

            base.Visit(entityType); 
 
            #endregion
 
            this.AddObjectEndDumpToHashBuilder();
        }

        protected override void Visit(AssociationSetEnd associationSetEnd) 
        {
            int index; 
            if (!this.AddObjectToSeenListAndHashBuilder(associationSetEnd, out index)) 
            {
                return; 
            }

            this.AddObjectStartDumpToHashBuilder(associationSetEnd, index);
 
            #region Inner data visit
            this.AddObjectContentToHashBuilder(associationSetEnd.Identity); 
            // Name is covered by Identity 

            base.Visit(associationSetEnd); 

            #endregion

            this.AddObjectEndDumpToHashBuilder(); 
        }
 
        protected override void Visit(AssociationType associationType) 
        {
            int index; 
            if (!this.AddObjectToSeenListAndHashBuilder(associationType, out index))
            {
                return;
            } 

            this.AddObjectStartDumpToHashBuilder(associationType, index); 
 
            #region Inner data visit
            this.AddObjectContentToHashBuilder(associationType.Abstract); 
            this.AddObjectContentToHashBuilder(associationType.Identity);
            // FullName, Namespace, and Name are all covered by Identity

            base.Visit(associationType); 

            #endregion 
 
            this.AddObjectEndDumpToHashBuilder();
        } 

        protected override void Visit(EdmProperty edmProperty)
        {
            int index; 
            if (!this.AddObjectToSeenListAndHashBuilder(edmProperty, out index))
            { 
                return; 
            }
 
            this.AddObjectStartDumpToHashBuilder(edmProperty, index);

            #region Inner data visit
            // since the delaring type is fixed and referenced to the upper type, 
            // there is no need to hash this
            //this.AddObjectContentToHashBuilder(edmProperty.DeclaringType); 
            this.AddObjectContentToHashBuilder(edmProperty.DefaultValue); 
            this.AddObjectContentToHashBuilder(edmProperty.Identity);
            // Name is covered by Identity 
            this.AddObjectContentToHashBuilder(edmProperty.IsStoreGeneratedComputed);
            this.AddObjectContentToHashBuilder(edmProperty.IsStoreGeneratedIdentity);
            this.AddObjectContentToHashBuilder(edmProperty.Nullable);
 
            base.Visit(edmProperty);
 
            #endregion 

            this.AddObjectEndDumpToHashBuilder(); 
        }

        protected override void Visit(NavigationProperty navigationProperty)
        { 
            // navigation properties are not considered in view generation
            return; 
        } 

        protected override void Visit(EdmMember edmMember) 
        {
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(edmMember, out index))
            { 
                return;
            } 
 
            this.AddObjectStartDumpToHashBuilder(edmMember, index);
 
            #region Inner data visit
            this.AddObjectContentToHashBuilder(edmMember.Identity);
            // Name is covered by Identity
            this.AddObjectContentToHashBuilder(edmMember.IsStoreGeneratedComputed); 
            this.AddObjectContentToHashBuilder(edmMember.IsStoreGeneratedIdentity);
 
            base.Visit(edmMember); 

            #endregion 

            this.AddObjectEndDumpToHashBuilder();
        }
 
        protected override void Visit(AssociationEndMember associationEndMember)
        { 
            int index; 
            if (!this.AddObjectToSeenListAndHashBuilder(associationEndMember, out index))
            { 
                return;
            }

            this.AddObjectStartDumpToHashBuilder(associationEndMember, index); 

            #region Inner data visit 
            this.AddObjectContentToHashBuilder(associationEndMember.DeleteBehavior); 
            this.AddObjectContentToHashBuilder(associationEndMember.Identity);
            // Name is covered by Identity 
            this.AddObjectContentToHashBuilder(associationEndMember.IsStoreGeneratedComputed);
            this.AddObjectContentToHashBuilder(associationEndMember.IsStoreGeneratedIdentity);
            this.AddObjectContentToHashBuilder(associationEndMember.RelationshipMultiplicity);
 
            base.Visit(associationEndMember);
 
            #endregion 

            this.AddObjectEndDumpToHashBuilder(); 
        }

        protected override void Visit(ReferentialConstraint referentialConstraint)
        { 
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(referentialConstraint, out index)) 
            { 
                return;
            } 

            this.AddObjectStartDumpToHashBuilder(referentialConstraint, index);

            #region Inner data visit 
            this.AddObjectContentToHashBuilder(referentialConstraint.Identity);
 
            base.Visit(referentialConstraint); 

            #endregion 

            this.AddObjectEndDumpToHashBuilder();
        }
 
        protected override void Visit(RelationshipEndMember relationshipEndMember)
        { 
            int index; 
            if (!this.AddObjectToSeenListAndHashBuilder(relationshipEndMember, out index))
            { 
                return;
            }

            this.AddObjectStartDumpToHashBuilder(relationshipEndMember, index); 

            #region Inner data visit 
            this.AddObjectContentToHashBuilder(relationshipEndMember.DeleteBehavior); 
            this.AddObjectContentToHashBuilder(relationshipEndMember.Identity);
            // Name is covered by Identity 
            this.AddObjectContentToHashBuilder(relationshipEndMember.IsStoreGeneratedComputed);
            this.AddObjectContentToHashBuilder(relationshipEndMember.IsStoreGeneratedIdentity);
            this.AddObjectContentToHashBuilder(relationshipEndMember.RelationshipMultiplicity);
 
            base.Visit(relationshipEndMember);
 
            #endregion 

            this.AddObjectEndDumpToHashBuilder(); 
        }

        protected override void Visit(TypeUsage typeUsage)
        { 
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(typeUsage, out index)) 
            { 
                return;
            } 

            this.AddObjectStartDumpToHashBuilder(typeUsage, index);

            #region Inner data visit 
            //No need to add identity of TypeUsage to the hash since it would take into account
            //facets that viewgen would not care and we visit the important facets anyway. 
 
            base.Visit(typeUsage);
 
            #endregion

            this.AddObjectEndDumpToHashBuilder();
        } 

        protected override void Visit(RelationshipType relationshipType) 
        { 
            base.Visit(relationshipType);
        } 

        protected override void Visit(EdmType edmType)
        {
            base.Visit(edmType); 
        }
 
        protected override void Visit(EnumType enumType) 
        {
            Debug.Fail("We don't allow enumTypes publicly"); 
        }

        protected override void Visit(EnumMember enumMember)
        { 
            Debug.Fail("We don't allow enumMembers publicly");
        } 
 
        protected override void Visit(CollectionType collectionType)
        { 
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(collectionType, out index))
            {
                return; 
            }
 
            this.AddObjectStartDumpToHashBuilder(collectionType, index); 

            #region Inner data visit 
            this.AddObjectContentToHashBuilder(collectionType.Identity);
            // Identity contains Name, NamespaceName and FullName

            base.Visit(collectionType); 

            #endregion 
 
            this.AddObjectEndDumpToHashBuilder();
        } 

        protected override void Visit(RefType refType)
        {
            int index; 
            if (!this.AddObjectToSeenListAndHashBuilder(refType, out index))
            { 
                return; 
            }
 
            this.AddObjectStartDumpToHashBuilder(refType, index);

            #region Inner data visit
            this.AddObjectContentToHashBuilder(refType.Identity); 
            // Identity contains Name, NamespaceName and FullName
 
            base.Visit(refType); 

            #endregion 

            this.AddObjectEndDumpToHashBuilder();
        }
 
        protected override void Visit(EntityTypeBase entityTypeBase)
        { 
            base.Visit(entityTypeBase); 
        }
 
        protected override void Visit(Facet facet)
        {
            int index;
            if (facet.Name != DbProviderManifest.NullableFacetName) 
            {
                // skip all the non interesting facets 
                return; 
            }
 
            if (!this.AddObjectToSeenListAndHashBuilder(facet, out index))
            {
                return;
            } 

            this.AddObjectStartDumpToHashBuilder(facet, index); 
 
            #region Inner data visit
            this.AddObjectContentToHashBuilder(facet.Identity); 
            // Identity already contains Name
            this.AddObjectContentToHashBuilder(facet.Value);

            base.Visit(facet); 

            #endregion 
 
            this.AddObjectEndDumpToHashBuilder();
        } 

        protected override void Visit(EdmFunction edmFunction)
        {
            // View Generation doesn't deal with functions 
            // so just return;
        } 
 
        protected override void Visit(ComplexType complexType)
        { 
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(complexType, out index))
            {
                return; 
            }
 
            this.AddObjectStartDumpToHashBuilder(complexType, index); 

            #region Inner data visit 
            this.AddObjectContentToHashBuilder(complexType.Abstract);
            this.AddObjectContentToHashBuilder(complexType.Identity);
            // Identity covers, FullName, Name, and NamespaceName
 
            base.Visit(complexType);
 
            #endregion 

            this.AddObjectEndDumpToHashBuilder(); 
        }

        protected override void Visit(PrimitiveType primitiveType)
        { 
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(primitiveType, out index)) 
            { 
                return;
            } 

            this.AddObjectStartDumpToHashBuilder(primitiveType, index);

            #region Inner data visit 
            this.AddObjectContentToHashBuilder(primitiveType.Name);
            this.AddObjectContentToHashBuilder(primitiveType.NamespaceName); 
 
            base.Visit(primitiveType);
 
            #endregion

            this.AddObjectEndDumpToHashBuilder();
        } 

        protected override void Visit(FunctionParameter functionParameter) 
        { 
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(functionParameter, out index)) 
            {
                return;
            }
 
            this.AddObjectStartDumpToHashBuilder(functionParameter, index);
 
            #region Inner data visit 
            this.AddObjectContentToHashBuilder(functionParameter.Identity);
            // Identity already has Name 
            this.AddObjectContentToHashBuilder(functionParameter.Mode);

            base.Visit(functionParameter);
 
            #endregion
 
            this.AddObjectEndDumpToHashBuilder(); 
        }
 
        protected override void Visit(DbProviderManifest providerManifest)
        {
            // the provider manifest will be checked by all the other types lining up.
            // no need to store more info. 
        }
        #endregion 
 
        #region hasher helper method
 
        internal string HashValue
        {
            get
            { 
                return m_hashSourceBuilder.ComputeHash();
            } 
        } 

        private void Clean() 
        {
            this.m_hashSourceBuilder = new CompressingHashBuilder(MetadataHelper.CreateMetadataHashAlgorithm(m_MappingVersion));
            this.m_instanceNumber = 0;
            this.m_itemsAlreadySeen = new Dictionary(); 
        }
 
        ///  
        /// if already seen, then out the object instance index, return false;
        /// if haven't seen, then add it to the m_itemAlreadySeen, out the current index, return true 
        /// 
        /// 
        /// 
        ///  
        private bool TryAddSeenItem(Object o, out int indexSeen)
        { 
            if (!this.m_itemsAlreadySeen.TryGetValue(o, out indexSeen)) 
            {
                this.m_itemsAlreadySeen.Add(o, this.m_instanceNumber); 

                indexSeen = this.m_instanceNumber;
                this.m_instanceNumber++;
 
                return true;
            } 
            return false; 
        }
 
        /// 
        /// if the object has seen, then add the seen object style to the hash source, return false;
        /// if not, then add it to the seen list, and append the object start dump to the hash source, return true
        ///  
        /// 
        ///  
        private bool AddObjectToSeenListAndHashBuilder(object o, out int instanceIndex) 
        {
            if (o == null) 
            {
                instanceIndex = -1;
                return false;
            } 
            if (!TryAddSeenItem(o, out instanceIndex))
            { 
                this.AddObjectStartDumpToHashBuilder(o, instanceIndex); 
                this.AddSeenObjectToHashBuilder(o, instanceIndex);
                this.AddObjectEndDumpToHashBuilder(); 
                return false;
            }
            return true;
        } 

        private void AddSeenObjectToHashBuilder(object o, int instanceIndex) 
        { 
            Debug.Assert(instanceIndex >= 0, "referencing index should not be less than 0");
            this.m_hashSourceBuilder.AppendLine("Instance Reference: " + instanceIndex); 
        }

        private void AddObjectStartDumpToHashBuilder(object o, int objectIndex)
        { 
            this.m_hashSourceBuilder.AppendObjectStartDump(o, objectIndex);
        } 
 
        private void AddObjectEndDumpToHashBuilder()
        { 
            this.m_hashSourceBuilder.AppendObjectEndDump();
        }

        private void AddObjectContentToHashBuilder(object content) 
        {
            if (content != null) 
            { 
                IFormattable formatContent = content as IFormattable;
                if (formatContent != null) 
                {
                    // if the content is formattable, the following code made it culture invariant,
                    // for instance, the int, "30,000" can be formatted to "30-000" if the user
                    // has a different language and region setting 
                    this.m_hashSourceBuilder.AppendLine(formatContent.ToString(null, CultureInfo.InvariantCulture));
                } 
                else 
                {
                    this.m_hashSourceBuilder.AppendLine(content.ToString()); 
                }
            }
            else
            { 
                this.m_hashSourceBuilder.AppendLine("NULL");
            } 
        } 

        ///  
        /// Add V2 schema properties and attributes to the hash builder
        /// 
        /// 
        ///  
        private void AddV2ObjectContentToHashBuilder(object content, double version)
        { 
            // if the version number is greater than or equal to V2, then we add the value 
            if (version >= XmlConstants.EdmVersionForV2)
            { 
                this.AddObjectContentToHashBuilder(content);
            }
        }
 
        internal static string GetMappingClosureHash(double mappingVersion, StorageEntityContainerMapping storageEntityContainerMapping)
        { 
            Debug.Assert(storageEntityContainerMapping != null, "storageEntityContainerMapping is null!"); 

            MetadataMappingHasherVisitor visitor = new MetadataMappingHasherVisitor(mappingVersion); 
            visitor.Visit(storageEntityContainerMapping);
            return visitor.HashValue;
        }
        #endregion 

    } 
} 

// 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.Generic;
using System.Linq;
using System.Text;
using System.Data.Metadata.Edm; 
using System.Data.Common;
using System.Data.Common.Utils; 
using System.Data.Mapping; 
using System.Diagnostics;
using System.Globalization; 


namespace System.Data.Mapping
{ 
    internal partial class MetadataMappingHasherVisitor : BaseMetadataMappingVisitor
    { 
        private CompressingHashBuilder m_hashSourceBuilder; 
        private Dictionary m_itemsAlreadySeen = new Dictionary();
        private int m_instanceNumber = 0; 
        private EdmItemCollection m_EdmItemCollection;
        private double m_EdmVersion;
        private double m_MappingVersion;
 
        private MetadataMappingHasherVisitor(double mappingVersion)
        { 
            m_MappingVersion = mappingVersion; 
            this.m_hashSourceBuilder = new CompressingHashBuilder(MetadataHelper.CreateMetadataHashAlgorithm(m_MappingVersion));
        } 

        #region visitor method
        protected override void Visit(StorageEntityContainerMapping storageEntityContainerMapping)
        { 
            Debug.Assert(storageEntityContainerMapping != null, "storageEntityContainerMapping cannot be null!");
 
            // at the entry point of visitor, we setup the versions 
            Debug.Assert(m_MappingVersion == storageEntityContainerMapping.StorageMappingItemCollection.MappingVersion, "the original version and the mapping collection version are not the same");
            this.m_MappingVersion = storageEntityContainerMapping.StorageMappingItemCollection.MappingVersion; 
            this.m_EdmVersion = storageEntityContainerMapping.StorageMappingItemCollection.EdmItemCollection.EdmVersion;

            this.m_EdmItemCollection = storageEntityContainerMapping.StorageMappingItemCollection.EdmItemCollection;
 
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(storageEntityContainerMapping, out index)) 
            { 
                // if this has been add to the seen list, then just
                return; 
            }
            if (this.m_itemsAlreadySeen.Count > 1)
            {
 
                // this means user try another visit over SECM, this is allowed but all the previous visit all lost due to clean
                // user can visit different SECM objects by using the same visitor to load the SECM object 
                this.Clean(); 
                Visit(storageEntityContainerMapping);
                return; 
            }

            this.AddObjectStartDumpToHashBuilder(storageEntityContainerMapping, index);
 
            #region Inner data visit
 
            this.AddObjectContentToHashBuilder(storageEntityContainerMapping.Identity); 

            this.AddV2ObjectContentToHashBuilder(storageEntityContainerMapping.GenerateUpdateViews, this.m_MappingVersion); 

            base.Visit(storageEntityContainerMapping);

            #endregion 

            this.AddObjectEndDumpToHashBuilder(); 
        } 

        protected override void Visit(EntityContainer entityContainer) 
        {
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(entityContainer, out index))
            { 
                return;
            } 
 
            this.AddObjectStartDumpToHashBuilder(entityContainer, index);
 
            #region Inner data visit

            this.AddObjectContentToHashBuilder(entityContainer.Identity);
            // Name is covered by Identity 

            base.Visit(entityContainer); 
 
            #endregion
 
            this.AddObjectEndDumpToHashBuilder();
        }

        protected override void Visit(StorageSetMapping storageSetMapping) 
        {
            int index; 
            if (!this.AddObjectToSeenListAndHashBuilder(storageSetMapping, out index)) 
            {
                return; 
            }

            this.AddObjectStartDumpToHashBuilder(storageSetMapping, index);
 
            #region Inner data visit
            base.Visit(storageSetMapping); 
            #endregion 

            this.AddObjectEndDumpToHashBuilder(); 
        }

        protected override void Visit(StorageTypeMapping storageTypeMapping)
        { 
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(storageTypeMapping, out index)) 
            { 
                return;
            } 

            this.AddObjectStartDumpToHashBuilder(storageTypeMapping, index);

            #region Inner data visit 

            base.Visit(storageTypeMapping); 
 
            #endregion
 
            this.AddObjectEndDumpToHashBuilder();
        }

        protected override void Visit(StorageMappingFragment storageMappingFragment) 
        {
            int index; 
            if (!this.AddObjectToSeenListAndHashBuilder(storageMappingFragment, out index)) 
            {
                return; 
            }

            this.AddObjectStartDumpToHashBuilder(storageMappingFragment, index);
 
            #region Inner data visit
 
            this.AddV2ObjectContentToHashBuilder(storageMappingFragment.IsSQueryDistinct, this.m_MappingVersion); 

            base.Visit(storageMappingFragment); 

            #endregion

            this.AddObjectEndDumpToHashBuilder(); 
        }
 
        protected override void Visit(StoragePropertyMapping storagePropertyMapping) 
        {
            base.Visit(storagePropertyMapping); 
        }

        protected override void Visit(StorageComplexPropertyMapping storageComplexPropertyMapping)
        { 
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(storageComplexPropertyMapping, out index)) 
            { 
                return;
            } 

            this.AddObjectStartDumpToHashBuilder(storageComplexPropertyMapping, index);

            #region Inner data visit 

            base.Visit(storageComplexPropertyMapping); 
 
            #endregion
 
            this.AddObjectEndDumpToHashBuilder();
        }
        protected override void Visit(StorageComplexTypeMapping storageComplexTypeMapping)
        { 
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(storageComplexTypeMapping, out index)) 
            { 
                return;
            } 

            this.AddObjectStartDumpToHashBuilder(storageComplexTypeMapping, index);

            #region Inner data visit 

            base.Visit(storageComplexTypeMapping); 
 
            #endregion
 
            this.AddObjectEndDumpToHashBuilder();
        }

        protected override void Visit(StorageConditionPropertyMapping storageConditionPropertyMapping) 
        {
            int index; 
            if (!this.AddObjectToSeenListAndHashBuilder(storageConditionPropertyMapping, out index)) 
            {
                return; 
            }

            this.AddObjectStartDumpToHashBuilder(storageConditionPropertyMapping, index);
 
            #region Inner data visit
            this.AddObjectContentToHashBuilder(storageConditionPropertyMapping.IsNull); 
            this.AddObjectContentToHashBuilder(storageConditionPropertyMapping.Value); 

            base.Visit(storageConditionPropertyMapping); 

            #endregion

            this.AddObjectEndDumpToHashBuilder(); 
        }
 
        protected override void Visit(StorageScalarPropertyMapping storageScalarPropertyMapping) 
        {
            int index; 
            if (!this.AddObjectToSeenListAndHashBuilder(storageScalarPropertyMapping, out index))
            {
                return;
            } 

            this.AddObjectStartDumpToHashBuilder(storageScalarPropertyMapping, index); 
 
            #region Inner data visit
 
            base.Visit(storageScalarPropertyMapping);

            #endregion
 
            this.AddObjectEndDumpToHashBuilder();
        } 
 
        protected override void Visit(EntitySetBase entitySetBase)
        { 
            base.Visit(entitySetBase);
        }

        protected override void Visit(EntitySet entitySet) 
        {
            int index; 
            if (!this.AddObjectToSeenListAndHashBuilder(entitySet, out index)) 
            {
                return; 
            }
            #region Inner data visit

            this.AddObjectStartDumpToHashBuilder(entitySet, index); 
            this.AddObjectContentToHashBuilder(entitySet.Name);
            this.AddObjectContentToHashBuilder(entitySet.Schema); 
            this.AddObjectContentToHashBuilder(entitySet.Table); 

            base.Visit(entitySet); 

            foreach (var entityType in MetadataHelper.GetTypeAndSubtypesOf(entitySet.ElementType, this.m_EdmItemCollection, false).Where(type => type != entitySet.ElementType))
            {
                this.Visit(entityType); 
            }
 
            #endregion 

            this.AddObjectEndDumpToHashBuilder(); 
        }

        protected override void Visit(AssociationSet associationSet)
        { 
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(associationSet, out index)) 
            { 
                return;
            } 

            this.AddObjectStartDumpToHashBuilder(associationSet, index);

            #region Inner data visit 
            this.AddObjectContentToHashBuilder(associationSet.CachedProviderSql);
            // Name is coverd by Identity 
            this.AddObjectContentToHashBuilder(associationSet.Identity); 
            this.AddObjectContentToHashBuilder(associationSet.Schema);
            this.AddObjectContentToHashBuilder(associationSet.Table); 

            base.Visit(associationSet);

            #endregion 

            this.AddObjectEndDumpToHashBuilder(); 
        } 

        protected override void Visit(EntityType entityType) 
        {
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(entityType, out index))
            { 
                return;
            } 
 
            this.AddObjectStartDumpToHashBuilder(entityType, index);
 
            #region Inner data visit
            this.AddObjectContentToHashBuilder(entityType.Abstract);
            this.AddObjectContentToHashBuilder(entityType.Identity);
            // FullName, Namespace and Name are all covered by Identity 

            base.Visit(entityType); 
 
            #endregion
 
            this.AddObjectEndDumpToHashBuilder();
        }

        protected override void Visit(AssociationSetEnd associationSetEnd) 
        {
            int index; 
            if (!this.AddObjectToSeenListAndHashBuilder(associationSetEnd, out index)) 
            {
                return; 
            }

            this.AddObjectStartDumpToHashBuilder(associationSetEnd, index);
 
            #region Inner data visit
            this.AddObjectContentToHashBuilder(associationSetEnd.Identity); 
            // Name is covered by Identity 

            base.Visit(associationSetEnd); 

            #endregion

            this.AddObjectEndDumpToHashBuilder(); 
        }
 
        protected override void Visit(AssociationType associationType) 
        {
            int index; 
            if (!this.AddObjectToSeenListAndHashBuilder(associationType, out index))
            {
                return;
            } 

            this.AddObjectStartDumpToHashBuilder(associationType, index); 
 
            #region Inner data visit
            this.AddObjectContentToHashBuilder(associationType.Abstract); 
            this.AddObjectContentToHashBuilder(associationType.Identity);
            // FullName, Namespace, and Name are all covered by Identity

            base.Visit(associationType); 

            #endregion 
 
            this.AddObjectEndDumpToHashBuilder();
        } 

        protected override void Visit(EdmProperty edmProperty)
        {
            int index; 
            if (!this.AddObjectToSeenListAndHashBuilder(edmProperty, out index))
            { 
                return; 
            }
 
            this.AddObjectStartDumpToHashBuilder(edmProperty, index);

            #region Inner data visit
            // since the delaring type is fixed and referenced to the upper type, 
            // there is no need to hash this
            //this.AddObjectContentToHashBuilder(edmProperty.DeclaringType); 
            this.AddObjectContentToHashBuilder(edmProperty.DefaultValue); 
            this.AddObjectContentToHashBuilder(edmProperty.Identity);
            // Name is covered by Identity 
            this.AddObjectContentToHashBuilder(edmProperty.IsStoreGeneratedComputed);
            this.AddObjectContentToHashBuilder(edmProperty.IsStoreGeneratedIdentity);
            this.AddObjectContentToHashBuilder(edmProperty.Nullable);
 
            base.Visit(edmProperty);
 
            #endregion 

            this.AddObjectEndDumpToHashBuilder(); 
        }

        protected override void Visit(NavigationProperty navigationProperty)
        { 
            // navigation properties are not considered in view generation
            return; 
        } 

        protected override void Visit(EdmMember edmMember) 
        {
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(edmMember, out index))
            { 
                return;
            } 
 
            this.AddObjectStartDumpToHashBuilder(edmMember, index);
 
            #region Inner data visit
            this.AddObjectContentToHashBuilder(edmMember.Identity);
            // Name is covered by Identity
            this.AddObjectContentToHashBuilder(edmMember.IsStoreGeneratedComputed); 
            this.AddObjectContentToHashBuilder(edmMember.IsStoreGeneratedIdentity);
 
            base.Visit(edmMember); 

            #endregion 

            this.AddObjectEndDumpToHashBuilder();
        }
 
        protected override void Visit(AssociationEndMember associationEndMember)
        { 
            int index; 
            if (!this.AddObjectToSeenListAndHashBuilder(associationEndMember, out index))
            { 
                return;
            }

            this.AddObjectStartDumpToHashBuilder(associationEndMember, index); 

            #region Inner data visit 
            this.AddObjectContentToHashBuilder(associationEndMember.DeleteBehavior); 
            this.AddObjectContentToHashBuilder(associationEndMember.Identity);
            // Name is covered by Identity 
            this.AddObjectContentToHashBuilder(associationEndMember.IsStoreGeneratedComputed);
            this.AddObjectContentToHashBuilder(associationEndMember.IsStoreGeneratedIdentity);
            this.AddObjectContentToHashBuilder(associationEndMember.RelationshipMultiplicity);
 
            base.Visit(associationEndMember);
 
            #endregion 

            this.AddObjectEndDumpToHashBuilder(); 
        }

        protected override void Visit(ReferentialConstraint referentialConstraint)
        { 
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(referentialConstraint, out index)) 
            { 
                return;
            } 

            this.AddObjectStartDumpToHashBuilder(referentialConstraint, index);

            #region Inner data visit 
            this.AddObjectContentToHashBuilder(referentialConstraint.Identity);
 
            base.Visit(referentialConstraint); 

            #endregion 

            this.AddObjectEndDumpToHashBuilder();
        }
 
        protected override void Visit(RelationshipEndMember relationshipEndMember)
        { 
            int index; 
            if (!this.AddObjectToSeenListAndHashBuilder(relationshipEndMember, out index))
            { 
                return;
            }

            this.AddObjectStartDumpToHashBuilder(relationshipEndMember, index); 

            #region Inner data visit 
            this.AddObjectContentToHashBuilder(relationshipEndMember.DeleteBehavior); 
            this.AddObjectContentToHashBuilder(relationshipEndMember.Identity);
            // Name is covered by Identity 
            this.AddObjectContentToHashBuilder(relationshipEndMember.IsStoreGeneratedComputed);
            this.AddObjectContentToHashBuilder(relationshipEndMember.IsStoreGeneratedIdentity);
            this.AddObjectContentToHashBuilder(relationshipEndMember.RelationshipMultiplicity);
 
            base.Visit(relationshipEndMember);
 
            #endregion 

            this.AddObjectEndDumpToHashBuilder(); 
        }

        protected override void Visit(TypeUsage typeUsage)
        { 
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(typeUsage, out index)) 
            { 
                return;
            } 

            this.AddObjectStartDumpToHashBuilder(typeUsage, index);

            #region Inner data visit 
            //No need to add identity of TypeUsage to the hash since it would take into account
            //facets that viewgen would not care and we visit the important facets anyway. 
 
            base.Visit(typeUsage);
 
            #endregion

            this.AddObjectEndDumpToHashBuilder();
        } 

        protected override void Visit(RelationshipType relationshipType) 
        { 
            base.Visit(relationshipType);
        } 

        protected override void Visit(EdmType edmType)
        {
            base.Visit(edmType); 
        }
 
        protected override void Visit(EnumType enumType) 
        {
            Debug.Fail("We don't allow enumTypes publicly"); 
        }

        protected override void Visit(EnumMember enumMember)
        { 
            Debug.Fail("We don't allow enumMembers publicly");
        } 
 
        protected override void Visit(CollectionType collectionType)
        { 
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(collectionType, out index))
            {
                return; 
            }
 
            this.AddObjectStartDumpToHashBuilder(collectionType, index); 

            #region Inner data visit 
            this.AddObjectContentToHashBuilder(collectionType.Identity);
            // Identity contains Name, NamespaceName and FullName

            base.Visit(collectionType); 

            #endregion 
 
            this.AddObjectEndDumpToHashBuilder();
        } 

        protected override void Visit(RefType refType)
        {
            int index; 
            if (!this.AddObjectToSeenListAndHashBuilder(refType, out index))
            { 
                return; 
            }
 
            this.AddObjectStartDumpToHashBuilder(refType, index);

            #region Inner data visit
            this.AddObjectContentToHashBuilder(refType.Identity); 
            // Identity contains Name, NamespaceName and FullName
 
            base.Visit(refType); 

            #endregion 

            this.AddObjectEndDumpToHashBuilder();
        }
 
        protected override void Visit(EntityTypeBase entityTypeBase)
        { 
            base.Visit(entityTypeBase); 
        }
 
        protected override void Visit(Facet facet)
        {
            int index;
            if (facet.Name != DbProviderManifest.NullableFacetName) 
            {
                // skip all the non interesting facets 
                return; 
            }
 
            if (!this.AddObjectToSeenListAndHashBuilder(facet, out index))
            {
                return;
            } 

            this.AddObjectStartDumpToHashBuilder(facet, index); 
 
            #region Inner data visit
            this.AddObjectContentToHashBuilder(facet.Identity); 
            // Identity already contains Name
            this.AddObjectContentToHashBuilder(facet.Value);

            base.Visit(facet); 

            #endregion 
 
            this.AddObjectEndDumpToHashBuilder();
        } 

        protected override void Visit(EdmFunction edmFunction)
        {
            // View Generation doesn't deal with functions 
            // so just return;
        } 
 
        protected override void Visit(ComplexType complexType)
        { 
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(complexType, out index))
            {
                return; 
            }
 
            this.AddObjectStartDumpToHashBuilder(complexType, index); 

            #region Inner data visit 
            this.AddObjectContentToHashBuilder(complexType.Abstract);
            this.AddObjectContentToHashBuilder(complexType.Identity);
            // Identity covers, FullName, Name, and NamespaceName
 
            base.Visit(complexType);
 
            #endregion 

            this.AddObjectEndDumpToHashBuilder(); 
        }

        protected override void Visit(PrimitiveType primitiveType)
        { 
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(primitiveType, out index)) 
            { 
                return;
            } 

            this.AddObjectStartDumpToHashBuilder(primitiveType, index);

            #region Inner data visit 
            this.AddObjectContentToHashBuilder(primitiveType.Name);
            this.AddObjectContentToHashBuilder(primitiveType.NamespaceName); 
 
            base.Visit(primitiveType);
 
            #endregion

            this.AddObjectEndDumpToHashBuilder();
        } 

        protected override void Visit(FunctionParameter functionParameter) 
        { 
            int index;
            if (!this.AddObjectToSeenListAndHashBuilder(functionParameter, out index)) 
            {
                return;
            }
 
            this.AddObjectStartDumpToHashBuilder(functionParameter, index);
 
            #region Inner data visit 
            this.AddObjectContentToHashBuilder(functionParameter.Identity);
            // Identity already has Name 
            this.AddObjectContentToHashBuilder(functionParameter.Mode);

            base.Visit(functionParameter);
 
            #endregion
 
            this.AddObjectEndDumpToHashBuilder(); 
        }
 
        protected override void Visit(DbProviderManifest providerManifest)
        {
            // the provider manifest will be checked by all the other types lining up.
            // no need to store more info. 
        }
        #endregion 
 
        #region hasher helper method
 
        internal string HashValue
        {
            get
            { 
                return m_hashSourceBuilder.ComputeHash();
            } 
        } 

        private void Clean() 
        {
            this.m_hashSourceBuilder = new CompressingHashBuilder(MetadataHelper.CreateMetadataHashAlgorithm(m_MappingVersion));
            this.m_instanceNumber = 0;
            this.m_itemsAlreadySeen = new Dictionary(); 
        }
 
        ///  
        /// if already seen, then out the object instance index, return false;
        /// if haven't seen, then add it to the m_itemAlreadySeen, out the current index, return true 
        /// 
        /// 
        /// 
        ///  
        private bool TryAddSeenItem(Object o, out int indexSeen)
        { 
            if (!this.m_itemsAlreadySeen.TryGetValue(o, out indexSeen)) 
            {
                this.m_itemsAlreadySeen.Add(o, this.m_instanceNumber); 

                indexSeen = this.m_instanceNumber;
                this.m_instanceNumber++;
 
                return true;
            } 
            return false; 
        }
 
        /// 
        /// if the object has seen, then add the seen object style to the hash source, return false;
        /// if not, then add it to the seen list, and append the object start dump to the hash source, return true
        ///  
        /// 
        ///  
        private bool AddObjectToSeenListAndHashBuilder(object o, out int instanceIndex) 
        {
            if (o == null) 
            {
                instanceIndex = -1;
                return false;
            } 
            if (!TryAddSeenItem(o, out instanceIndex))
            { 
                this.AddObjectStartDumpToHashBuilder(o, instanceIndex); 
                this.AddSeenObjectToHashBuilder(o, instanceIndex);
                this.AddObjectEndDumpToHashBuilder(); 
                return false;
            }
            return true;
        } 

        private void AddSeenObjectToHashBuilder(object o, int instanceIndex) 
        { 
            Debug.Assert(instanceIndex >= 0, "referencing index should not be less than 0");
            this.m_hashSourceBuilder.AppendLine("Instance Reference: " + instanceIndex); 
        }

        private void AddObjectStartDumpToHashBuilder(object o, int objectIndex)
        { 
            this.m_hashSourceBuilder.AppendObjectStartDump(o, objectIndex);
        } 
 
        private void AddObjectEndDumpToHashBuilder()
        { 
            this.m_hashSourceBuilder.AppendObjectEndDump();
        }

        private void AddObjectContentToHashBuilder(object content) 
        {
            if (content != null) 
            { 
                IFormattable formatContent = content as IFormattable;
                if (formatContent != null) 
                {
                    // if the content is formattable, the following code made it culture invariant,
                    // for instance, the int, "30,000" can be formatted to "30-000" if the user
                    // has a different language and region setting 
                    this.m_hashSourceBuilder.AppendLine(formatContent.ToString(null, CultureInfo.InvariantCulture));
                } 
                else 
                {
                    this.m_hashSourceBuilder.AppendLine(content.ToString()); 
                }
            }
            else
            { 
                this.m_hashSourceBuilder.AppendLine("NULL");
            } 
        } 

        ///  
        /// Add V2 schema properties and attributes to the hash builder
        /// 
        /// 
        ///  
        private void AddV2ObjectContentToHashBuilder(object content, double version)
        { 
            // if the version number is greater than or equal to V2, then we add the value 
            if (version >= XmlConstants.EdmVersionForV2)
            { 
                this.AddObjectContentToHashBuilder(content);
            }
        }
 
        internal static string GetMappingClosureHash(double mappingVersion, StorageEntityContainerMapping storageEntityContainerMapping)
        { 
            Debug.Assert(storageEntityContainerMapping != null, "storageEntityContainerMapping is null!"); 

            MetadataMappingHasherVisitor visitor = new MetadataMappingHasherVisitor(mappingVersion); 
            visitor.Visit(storageEntityContainerMapping);
            return visitor.HashValue;
        }
        #endregion 

    } 
} 

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