CompositeKey.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Map / Update / Internal / CompositeKey.cs / 1305376 / CompositeKey.cs

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

using System.Data.Common.Utils; 
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq; 
namespace System.Data.Mapping.Update.Internal
{ 
    ///  
    /// Represents a key composed of multiple parts.
    ///  
    internal class CompositeKey
    {
        #region Fields
        ///  
        /// Gets components of this composite key.
        ///  
        internal readonly PropagatorResult[] KeyComponents; 
        #endregion
 
        #region Constructors
        /// 
        /// Initialize a new composite key using the given constant values. Order is important.
        ///  
        /// Key values.
        internal CompositeKey(PropagatorResult[] constants) 
        { 
            Debug.Assert(null != constants, "key values must be given");
 
            KeyComponents = constants;
        }
        #endregion
 
        #region Methods
        ///  
        /// Creates a key comparer operating in the context of the given translator. 
        /// 
        internal static IEqualityComparer CreateComparer(KeyManager keyManager) 
        {
            return new CompositeKeyComparer(keyManager);
        }
 
        /// 
        /// Creates a merged key instance where each key component contains both elements. 
        ///  
        /// Must be a non-null compatible key (same number of components).
        /// Merged key. 
        internal CompositeKey Merge(KeyManager keyManager, CompositeKey other)
        {
            Debug.Assert(null != other && other.KeyComponents.Length == this.KeyComponents.Length, "expected a compatible CompositeKey");
            PropagatorResult[] mergedKeyValues = new PropagatorResult[this.KeyComponents.Length]; 
            for (int i = 0; i < this.KeyComponents.Length; i++)
            { 
                mergedKeyValues[i] = this.KeyComponents[i].Merge(keyManager, other.KeyComponents[i]); 
            }
            return new CompositeKey(mergedKeyValues); 
        }
        #endregion

        ///  
        /// Equality and comparison implementation for composite keys.
        ///  
        private class CompositeKeyComparer : IEqualityComparer 
        {
            private readonly KeyManager _manager; 

            internal CompositeKeyComparer(KeyManager manager)
            {
                _manager = EntityUtil.CheckArgumentNull(manager, "manager"); 
            }
 
            // determines equality by comparing each key component 
            public bool Equals(CompositeKey left, CompositeKey right)
            { 
                // Short circuit the comparison if we know the other reference is equivalent
                if (object.ReferenceEquals(left, right)) { return true; }

                // If either side is null, return false order (both can't be null because of 
                // the previous check)
                if (null == left || null == right) { return false; } 
 
                Debug.Assert(null != left.KeyComponents && null != right.KeyComponents,
                    "(Update/JoinPropagator) CompositeKey must be initialized"); 

                if (left.KeyComponents.Length != right.KeyComponents.Length) { return false; }

                for (int i = 0; i < left.KeyComponents.Length; i++) 
                {
                    PropagatorResult leftValue = left.KeyComponents[i]; 
                    PropagatorResult rightValue = right.KeyComponents[i]; 

                    // if both side are identifiers, check if they're the same or one is constrained by the 
                    // other (if there is a dependent-principal relationship, they get fixed up to the same
                    // value)
                    if (leftValue.Identifier != PropagatorResult.NullIdentifier)
                    { 
                        if (rightValue.Identifier == PropagatorResult.NullIdentifier ||
                            _manager.GetCliqueIdentifier(leftValue.Identifier) != _manager.GetCliqueIdentifier(rightValue.Identifier)) 
                        { 
                            return false;
                        } 
                    }
                    else
                    {
                        if (rightValue.Identifier != PropagatorResult.NullIdentifier || 
                            !ByValueEqualityComparer.Default.Equals(leftValue.GetSimpleValue(), rightValue.GetSimpleValue()))
                        { 
                            return false; 
                        }
                    } 
                }

                return true;
            } 

            // creates a hash code by XORing hash codes for all key components. 
            public int GetHashCode(CompositeKey key) 
            {
                EntityUtil.CheckArgumentNull(key, "key"); 

                int result = 0;
                foreach (PropagatorResult keyComponent in key.KeyComponents)
                { 
                    result = (result << 5) ^ GetComponentHashCode(keyComponent);
                } 
 
                return result;
            } 

            // Gets the value to use for hash code
            private int GetComponentHashCode(PropagatorResult keyComponent)
            { 
                if (keyComponent.Identifier == PropagatorResult.NullIdentifier)
                { 
                    // no identifier exists for this key component, so use the actual key 
                    // value
                    Debug.Assert(null != keyComponent && null != keyComponent, 
                        "key value must not be null");
                    return ByValueEqualityComparer.Default.GetHashCode(keyComponent.GetSimpleValue());
                }
                else 
                {
                    // use ID for FK graph clique (this ensures that keys fixed up to the same 
                    // value based on a constraint will have the same hash code) 
                    return _manager.GetCliqueIdentifier(keyComponent.Identifier).GetHashCode();
                } 
            }
        }
    }
} 

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