Validator.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 / Map / ViewGeneration / Validator.cs / 2 / Validator.cs

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

 
using System.Data.Common.Utils;
using System.Data.Mapping.ViewGeneration.Validation;
using System.Data.Mapping.ViewGeneration.Structures;
using System.Data.Mapping.ViewGeneration.Utils; 
using System.Collections.Generic;
using System.Diagnostics; 
using System.Collections.ObjectModel; 
using System.Data.Metadata.Edm;
using System.Linq; 

namespace System.Data.Mapping.ViewGeneration {

    using BasicSchemaConstraints = SchemaConstraints; 
    using ViewSchemaConstraints = SchemaConstraints;
    using System.Data.Entity; 
 
    // This class is responsible for validating the incoming cells for a schema
    class Validator { 

        #region Constructor
        // requires: cells are not normalized, i.e., no slot is null in the cell queries
        // effects: Constructs a validator object that is capable of 
        // validating all the schema cells together
        internal Validator(IEnumerable cells, ConfigViewGenerator config) { 
            m_cells = cells; 
            m_config = config;
            m_errorLog = new ErrorLog(); 
        }
        #endregion

        #region Fields 
        private IEnumerable m_cells;
        private ConfigViewGenerator m_config; 
        private ErrorLog m_errorLog; // Keeps track of errors for this set of cells 
        private ViewSchemaConstraints m_cViewConstraints;
        private ViewSchemaConstraints m_sViewConstraints; 
        #endregion

        #region External Methods
        // effects: Performs the validation of the cells in this and returns 
        // an error log of all the errors/warnings that were discovered
        internal ErrorLog Validate(MetadataWorkspace workspace) { 
 
            // Check for errors not checked by "C-implies-S principle"
            if (PerformSingleCellChecks() == false) { 
                return m_errorLog;
            }

            BasicSchemaConstraints cConstraints = new BasicSchemaConstraints(); 
            BasicSchemaConstraints sConstraints = new BasicSchemaConstraints();
 
            // Construct intermediate "view relations" and the basic cell 
            // relations along with the basic constraints
            ConstructCellRelationsWithConstraints(cConstraints, sConstraints, workspace); 

            if (m_config.IsVerboseTracing) {
                // Trace Basic constraints
                Trace.WriteLine(String.Empty); 
                Trace.WriteLine("C-Level Basic Constraints");
                Trace.WriteLine(cConstraints); 
                Trace.WriteLine("S-Level Basic Constraints"); 
                Trace.WriteLine(sConstraints);
            } 

            // Propagate the constraints
            m_cViewConstraints = PropagateConstraints(cConstraints);
            m_sViewConstraints = PropagateConstraints(sConstraints); 

            // Make some basic checks on the view and basic cell constraints 
            CheckConstraintSanity(cConstraints, sConstraints, m_cViewConstraints, m_sViewConstraints); 

            if (m_config.IsVerboseTracing) { 
                // Trace View constraints
                Trace.WriteLine(String.Empty);
                Trace.WriteLine("C-Level View Constraints");
                Trace.WriteLine(m_cViewConstraints); 
                Trace.WriteLine("S-Level View Constraints");
                Trace.WriteLine(m_sViewConstraints); 
            } 

            // Check for implication 
            CheckImplication(m_cViewConstraints, m_sViewConstraints, workspace);
            return m_errorLog;
        }
        #endregion 

        #region Basic Constraint Creation 
 
        // effects: Creates the base cell relation and view cell relations
        // for each cellquery/cell. Also generates the C-Side and S-side 
        // basic constraints and stores them into cConstraints and
        // sConstraints. Stores them in cConstraints and sConstraints
        private void ConstructCellRelationsWithConstraints(BasicSchemaConstraints cConstraints,
                                                           BasicSchemaConstraints sConstraints, 
                                                           MetadataWorkspace workspace) {
 
            // Populate single cell constraints 
            int cellNumber = 0;
            foreach (Cell cell in m_cells) { 
                // We have to create the ViewCellRelation so that the
                // BasicCellRelations can be created.
                cell.CreateViewCellRelation(cellNumber);
                BasicCellRelation cCellRelation = cell.CQuery.BasicCellRelation; 
                BasicCellRelation sCellRelation = cell.SQuery.BasicCellRelation;
                // Populate the constraints for the C relation and the S Relation 
                PopulateBaseConstraints(cCellRelation, cConstraints, workspace); 
                PopulateBaseConstraints(sCellRelation, sConstraints, workspace);
                cellNumber++; 
            }

            // Populate two-cell constraints, i.e., inclusion
            foreach (Cell firstCell in m_cells) { 
                foreach (Cell secondCell in m_cells) {
                    if (Object.ReferenceEquals(firstCell, secondCell)) { 
                        // We do not want to set up self-inclusion constraints unnecessarily 
                        continue;
                    } 
                }
            }
        }
 
        // effects: Generates the single-cell key+domain constraints for
        // baseRelation and adds them to constraints 
        private static void PopulateBaseConstraints(BasicCellRelation baseRelation, 
                                                    BasicSchemaConstraints constraints,
                                                    MetadataWorkspace workspace) { 
            // Populate key constraints
            baseRelation.PopulateKeyConstraints(constraints, workspace);
        }
        #endregion 

        #region Constraint Propagation 
        // effects: Propagates baseConstraints derived from the cellrelations 
        // to the corresponding viewCellRelations and returns the list of
        // propagated constraints 
        private static ViewSchemaConstraints PropagateConstraints(BasicSchemaConstraints baseConstraints) {
            ViewSchemaConstraints propagatedConstraints = new ViewSchemaConstraints();

            // Key constraint propagation 
            foreach (BasicKeyConstraint keyConstraint in baseConstraints.KeyConstraints) {
                ViewKeyConstraint viewConstraint = keyConstraint.Propagate(); 
                if (viewConstraint != null) { 
                    propagatedConstraints.Add(viewConstraint);
                } 
            }
            return propagatedConstraints;
        }
        #endregion 

        #region Checking for Implication 
        // effects: Checks if all sViewConstraints are implied by the 
        // constraints in cViewConstraints. If some S-level constraints are
        // not implied, adds errors/warnings to m_errorLog 
        private void CheckImplication(ViewSchemaConstraints cViewConstraints, ViewSchemaConstraints sViewConstraints, MetadataWorkspace workspace) {

            // Check key constraints
            // i.e., if S has a key , C must have a key that is a subset of this 
            CheckImplicationKeyConstraints(cViewConstraints, sViewConstraints, workspace);
 
            // For updates, we need to ensure the following: for every 
            // extent E, table T pair, some key of E is implied by T's key
 
            // Get all key constraints for each extent and each table
            KeyToListMap extentPairConstraints =
                new KeyToListMap(EqualityComparer.Default);
 
            foreach (ViewKeyConstraint cKeyConstraint in cViewConstraints.KeyConstraints) {
                ExtentPair pair = new ExtentPair(cKeyConstraint.Cell.CQuery.Extent, cKeyConstraint.Cell.SQuery.Extent); 
                extentPairConstraints.Add(pair, cKeyConstraint); 
            }
 
            // Now check that we guarantee at least one constraint per
            // extent/table pair
            foreach (ExtentPair extentPair in extentPairConstraints.Keys) {
                ReadOnlyCollection cKeyConstraints = extentPairConstraints.ListForKey(extentPair); 
                bool sImpliesSomeC = false;
                // Go through all key constraints for the extent/table pair, and find one that S implies 
                foreach (ViewKeyConstraint cKeyConstraint in cKeyConstraints) { 
                    foreach (ViewKeyConstraint sKeyConstraint in sViewConstraints.KeyConstraints) {
                        if (sKeyConstraint.Implies(cKeyConstraint)) { 
                            sImpliesSomeC = true;
                            break; // The implication holds - so no problem
                        }
                    } 
                }
                if (sImpliesSomeC == false) { 
                    // Indicate that at least one key must be ensured on the S-side 
                    m_errorLog.AddEntry(ViewKeyConstraint.GetErrorRecord(cKeyConstraints, workspace));
                } 
            }
        }

        // effects: Checks for key constraint implication problems from 
        // leftViewConstraints to rightViewConstraints. Adds errors/warning to m_errorLog
        private void CheckImplicationKeyConstraints(ViewSchemaConstraints leftViewConstraints, 
                                                    ViewSchemaConstraints rightViewConstraints, 
                                                    MetadataWorkspace workspace) {
 
            // if cImpliesS is true, every rightKeyConstraint must be implied
            // if it is false, at least one key constraint for each C-level
            // extent must be implied
 
            foreach (ViewKeyConstraint rightKeyConstraint in rightViewConstraints.KeyConstraints) {
                // Go through all the left Side constraints and check for implication 
                bool found = false; 
                foreach (ViewKeyConstraint leftKeyConstraint in leftViewConstraints.KeyConstraints) {
                    if (leftKeyConstraint.Implies(rightKeyConstraint)) { 
                        found = true;
                        break; // The implication holds - so no problem
                    }
                } 
                if (false == found) {
                    // No C-side key constraint implies this S-level key constraint 
                    // Report a problem 
                    m_errorLog.AddEntry(ViewKeyConstraint.GetErrorRecord(rightKeyConstraint, workspace));
                } 
            }
        }

        #endregion 

        #region Miscellaneous checks 
        // effects: Check for problems in each cell that are not detected by the 
        // "C-constraints-imply-S-constraints" principle. If the check fails,
        // adds relevant error info to m_errorLog and returns false. Else 
        // retrns true
        private bool PerformSingleCellChecks() {

            int errorLogSize = m_errorLog.Count; 
            foreach (Cell cell in m_cells) {
                // Is cell syntactically well-formed? 
                cell.CQuery.JoinTreeRoot.Validate(); 
                cell.SQuery.JoinTreeRoot.Validate();
                // Check for duplication of element in a single cell name1, name2 
                // -> name Could be done by implication but that would require
                // setting self-inclusion constraints etc That seems unnecessary

                // We need this check only for the C side. if we map cname1 
                // and cmane2 to sname, that is a problem. But mapping sname1
                // and sname2 to cname is ok 
                ErrorLog.Record error = cell.SQuery.CheckForDuplicateFields(cell.CQuery, cell); 
                if (error != null) {
                    m_errorLog.AddEntry(error); 
                }

                // Check that the EntityKey and the Table key are mapped
                // (Key for association is all ends) 
                error = cell.CQuery.VerifyKeysPresent(cell, Strings.ViewGen_EntitySetKey_Missing_1,
                    Strings.ViewGen_AssociationSetKey_Missing_2, ViewGenErrorCode.KeyNotMappedForCSideExtent); 
 
                if (error != null) {
                    m_errorLog.AddEntry(error); 
                }

                error = cell.SQuery.VerifyKeysPresent(cell, Strings.ViewGen_TableKey_Missing_1, null, ViewGenErrorCode.KeyNotMappedForTable);
                if (error != null) { 
                    m_errorLog.AddEntry(error);
                } 
 
                // Check that if any side has a not-null constraint -- if so,
                // we must project that slot 
                error = cell.CQuery.CheckForProjectedNotNullSlots(cell);
                if (error != null) {
                    m_errorLog.AddEntry(error);
                } 
                error = cell.SQuery.CheckForProjectedNotNullSlots(cell);
                if (error != null) { 
                    m_errorLog.AddEntry(error); 
                }
            } 
            return m_errorLog.Count == errorLogSize;
        }

        // effects: Checks for some sanity issues between the basic and view constraints. Adds to m_errorLog if needed 
        [Conditional("DEBUG")]
        private static void CheckConstraintSanity(BasicSchemaConstraints cConstraints, BasicSchemaConstraints sConstraints, 
                                           ViewSchemaConstraints cViewConstraints, ViewSchemaConstraints sViewConstraints) { 
            Debug.Assert(cConstraints.KeyConstraints.Count() == cViewConstraints.KeyConstraints.Count(),
                         "Mismatch in number of C basic and view key constraints"); 
            Debug.Assert(sConstraints.KeyConstraints.Count() == sViewConstraints.KeyConstraints.Count(),
                         "Mismatch in number of S basic and view key constraints");
        }
        #endregion 

        // Keeps track of two extent objects 
        private class ExtentPair { 
            internal ExtentPair(EntitySetBase acExtent, EntitySetBase asExtent) {
                cExtent = acExtent; 
                sExtent = asExtent;
            }
            internal EntitySetBase cExtent;
            internal EntitySetBase sExtent; 

            public override bool Equals(object obj) { 
                if (object.ReferenceEquals(this, obj)) { 
                    return true;
                } 
                ExtentPair pair = obj as ExtentPair;
                if (pair == null) {
                    return false;
                } 

                return pair.cExtent.Equals(cExtent) && pair.sExtent.Equals(sExtent); 
            } 

            public override int GetHashCode() { 
                return cExtent.GetHashCode() ^ sExtent.GetHashCode();
            }
        }
 

    } 
 
}

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

 
using System.Data.Common.Utils;
using System.Data.Mapping.ViewGeneration.Validation;
using System.Data.Mapping.ViewGeneration.Structures;
using System.Data.Mapping.ViewGeneration.Utils; 
using System.Collections.Generic;
using System.Diagnostics; 
using System.Collections.ObjectModel; 
using System.Data.Metadata.Edm;
using System.Linq; 

namespace System.Data.Mapping.ViewGeneration {

    using BasicSchemaConstraints = SchemaConstraints; 
    using ViewSchemaConstraints = SchemaConstraints;
    using System.Data.Entity; 
 
    // This class is responsible for validating the incoming cells for a schema
    class Validator { 

        #region Constructor
        // requires: cells are not normalized, i.e., no slot is null in the cell queries
        // effects: Constructs a validator object that is capable of 
        // validating all the schema cells together
        internal Validator(IEnumerable cells, ConfigViewGenerator config) { 
            m_cells = cells; 
            m_config = config;
            m_errorLog = new ErrorLog(); 
        }
        #endregion

        #region Fields 
        private IEnumerable m_cells;
        private ConfigViewGenerator m_config; 
        private ErrorLog m_errorLog; // Keeps track of errors for this set of cells 
        private ViewSchemaConstraints m_cViewConstraints;
        private ViewSchemaConstraints m_sViewConstraints; 
        #endregion

        #region External Methods
        // effects: Performs the validation of the cells in this and returns 
        // an error log of all the errors/warnings that were discovered
        internal ErrorLog Validate(MetadataWorkspace workspace) { 
 
            // Check for errors not checked by "C-implies-S principle"
            if (PerformSingleCellChecks() == false) { 
                return m_errorLog;
            }

            BasicSchemaConstraints cConstraints = new BasicSchemaConstraints(); 
            BasicSchemaConstraints sConstraints = new BasicSchemaConstraints();
 
            // Construct intermediate "view relations" and the basic cell 
            // relations along with the basic constraints
            ConstructCellRelationsWithConstraints(cConstraints, sConstraints, workspace); 

            if (m_config.IsVerboseTracing) {
                // Trace Basic constraints
                Trace.WriteLine(String.Empty); 
                Trace.WriteLine("C-Level Basic Constraints");
                Trace.WriteLine(cConstraints); 
                Trace.WriteLine("S-Level Basic Constraints"); 
                Trace.WriteLine(sConstraints);
            } 

            // Propagate the constraints
            m_cViewConstraints = PropagateConstraints(cConstraints);
            m_sViewConstraints = PropagateConstraints(sConstraints); 

            // Make some basic checks on the view and basic cell constraints 
            CheckConstraintSanity(cConstraints, sConstraints, m_cViewConstraints, m_sViewConstraints); 

            if (m_config.IsVerboseTracing) { 
                // Trace View constraints
                Trace.WriteLine(String.Empty);
                Trace.WriteLine("C-Level View Constraints");
                Trace.WriteLine(m_cViewConstraints); 
                Trace.WriteLine("S-Level View Constraints");
                Trace.WriteLine(m_sViewConstraints); 
            } 

            // Check for implication 
            CheckImplication(m_cViewConstraints, m_sViewConstraints, workspace);
            return m_errorLog;
        }
        #endregion 

        #region Basic Constraint Creation 
 
        // effects: Creates the base cell relation and view cell relations
        // for each cellquery/cell. Also generates the C-Side and S-side 
        // basic constraints and stores them into cConstraints and
        // sConstraints. Stores them in cConstraints and sConstraints
        private void ConstructCellRelationsWithConstraints(BasicSchemaConstraints cConstraints,
                                                           BasicSchemaConstraints sConstraints, 
                                                           MetadataWorkspace workspace) {
 
            // Populate single cell constraints 
            int cellNumber = 0;
            foreach (Cell cell in m_cells) { 
                // We have to create the ViewCellRelation so that the
                // BasicCellRelations can be created.
                cell.CreateViewCellRelation(cellNumber);
                BasicCellRelation cCellRelation = cell.CQuery.BasicCellRelation; 
                BasicCellRelation sCellRelation = cell.SQuery.BasicCellRelation;
                // Populate the constraints for the C relation and the S Relation 
                PopulateBaseConstraints(cCellRelation, cConstraints, workspace); 
                PopulateBaseConstraints(sCellRelation, sConstraints, workspace);
                cellNumber++; 
            }

            // Populate two-cell constraints, i.e., inclusion
            foreach (Cell firstCell in m_cells) { 
                foreach (Cell secondCell in m_cells) {
                    if (Object.ReferenceEquals(firstCell, secondCell)) { 
                        // We do not want to set up self-inclusion constraints unnecessarily 
                        continue;
                    } 
                }
            }
        }
 
        // effects: Generates the single-cell key+domain constraints for
        // baseRelation and adds them to constraints 
        private static void PopulateBaseConstraints(BasicCellRelation baseRelation, 
                                                    BasicSchemaConstraints constraints,
                                                    MetadataWorkspace workspace) { 
            // Populate key constraints
            baseRelation.PopulateKeyConstraints(constraints, workspace);
        }
        #endregion 

        #region Constraint Propagation 
        // effects: Propagates baseConstraints derived from the cellrelations 
        // to the corresponding viewCellRelations and returns the list of
        // propagated constraints 
        private static ViewSchemaConstraints PropagateConstraints(BasicSchemaConstraints baseConstraints) {
            ViewSchemaConstraints propagatedConstraints = new ViewSchemaConstraints();

            // Key constraint propagation 
            foreach (BasicKeyConstraint keyConstraint in baseConstraints.KeyConstraints) {
                ViewKeyConstraint viewConstraint = keyConstraint.Propagate(); 
                if (viewConstraint != null) { 
                    propagatedConstraints.Add(viewConstraint);
                } 
            }
            return propagatedConstraints;
        }
        #endregion 

        #region Checking for Implication 
        // effects: Checks if all sViewConstraints are implied by the 
        // constraints in cViewConstraints. If some S-level constraints are
        // not implied, adds errors/warnings to m_errorLog 
        private void CheckImplication(ViewSchemaConstraints cViewConstraints, ViewSchemaConstraints sViewConstraints, MetadataWorkspace workspace) {

            // Check key constraints
            // i.e., if S has a key , C must have a key that is a subset of this 
            CheckImplicationKeyConstraints(cViewConstraints, sViewConstraints, workspace);
 
            // For updates, we need to ensure the following: for every 
            // extent E, table T pair, some key of E is implied by T's key
 
            // Get all key constraints for each extent and each table
            KeyToListMap extentPairConstraints =
                new KeyToListMap(EqualityComparer.Default);
 
            foreach (ViewKeyConstraint cKeyConstraint in cViewConstraints.KeyConstraints) {
                ExtentPair pair = new ExtentPair(cKeyConstraint.Cell.CQuery.Extent, cKeyConstraint.Cell.SQuery.Extent); 
                extentPairConstraints.Add(pair, cKeyConstraint); 
            }
 
            // Now check that we guarantee at least one constraint per
            // extent/table pair
            foreach (ExtentPair extentPair in extentPairConstraints.Keys) {
                ReadOnlyCollection cKeyConstraints = extentPairConstraints.ListForKey(extentPair); 
                bool sImpliesSomeC = false;
                // Go through all key constraints for the extent/table pair, and find one that S implies 
                foreach (ViewKeyConstraint cKeyConstraint in cKeyConstraints) { 
                    foreach (ViewKeyConstraint sKeyConstraint in sViewConstraints.KeyConstraints) {
                        if (sKeyConstraint.Implies(cKeyConstraint)) { 
                            sImpliesSomeC = true;
                            break; // The implication holds - so no problem
                        }
                    } 
                }
                if (sImpliesSomeC == false) { 
                    // Indicate that at least one key must be ensured on the S-side 
                    m_errorLog.AddEntry(ViewKeyConstraint.GetErrorRecord(cKeyConstraints, workspace));
                } 
            }
        }

        // effects: Checks for key constraint implication problems from 
        // leftViewConstraints to rightViewConstraints. Adds errors/warning to m_errorLog
        private void CheckImplicationKeyConstraints(ViewSchemaConstraints leftViewConstraints, 
                                                    ViewSchemaConstraints rightViewConstraints, 
                                                    MetadataWorkspace workspace) {
 
            // if cImpliesS is true, every rightKeyConstraint must be implied
            // if it is false, at least one key constraint for each C-level
            // extent must be implied
 
            foreach (ViewKeyConstraint rightKeyConstraint in rightViewConstraints.KeyConstraints) {
                // Go through all the left Side constraints and check for implication 
                bool found = false; 
                foreach (ViewKeyConstraint leftKeyConstraint in leftViewConstraints.KeyConstraints) {
                    if (leftKeyConstraint.Implies(rightKeyConstraint)) { 
                        found = true;
                        break; // The implication holds - so no problem
                    }
                } 
                if (false == found) {
                    // No C-side key constraint implies this S-level key constraint 
                    // Report a problem 
                    m_errorLog.AddEntry(ViewKeyConstraint.GetErrorRecord(rightKeyConstraint, workspace));
                } 
            }
        }

        #endregion 

        #region Miscellaneous checks 
        // effects: Check for problems in each cell that are not detected by the 
        // "C-constraints-imply-S-constraints" principle. If the check fails,
        // adds relevant error info to m_errorLog and returns false. Else 
        // retrns true
        private bool PerformSingleCellChecks() {

            int errorLogSize = m_errorLog.Count; 
            foreach (Cell cell in m_cells) {
                // Is cell syntactically well-formed? 
                cell.CQuery.JoinTreeRoot.Validate(); 
                cell.SQuery.JoinTreeRoot.Validate();
                // Check for duplication of element in a single cell name1, name2 
                // -> name Could be done by implication but that would require
                // setting self-inclusion constraints etc That seems unnecessary

                // We need this check only for the C side. if we map cname1 
                // and cmane2 to sname, that is a problem. But mapping sname1
                // and sname2 to cname is ok 
                ErrorLog.Record error = cell.SQuery.CheckForDuplicateFields(cell.CQuery, cell); 
                if (error != null) {
                    m_errorLog.AddEntry(error); 
                }

                // Check that the EntityKey and the Table key are mapped
                // (Key for association is all ends) 
                error = cell.CQuery.VerifyKeysPresent(cell, Strings.ViewGen_EntitySetKey_Missing_1,
                    Strings.ViewGen_AssociationSetKey_Missing_2, ViewGenErrorCode.KeyNotMappedForCSideExtent); 
 
                if (error != null) {
                    m_errorLog.AddEntry(error); 
                }

                error = cell.SQuery.VerifyKeysPresent(cell, Strings.ViewGen_TableKey_Missing_1, null, ViewGenErrorCode.KeyNotMappedForTable);
                if (error != null) { 
                    m_errorLog.AddEntry(error);
                } 
 
                // Check that if any side has a not-null constraint -- if so,
                // we must project that slot 
                error = cell.CQuery.CheckForProjectedNotNullSlots(cell);
                if (error != null) {
                    m_errorLog.AddEntry(error);
                } 
                error = cell.SQuery.CheckForProjectedNotNullSlots(cell);
                if (error != null) { 
                    m_errorLog.AddEntry(error); 
                }
            } 
            return m_errorLog.Count == errorLogSize;
        }

        // effects: Checks for some sanity issues between the basic and view constraints. Adds to m_errorLog if needed 
        [Conditional("DEBUG")]
        private static void CheckConstraintSanity(BasicSchemaConstraints cConstraints, BasicSchemaConstraints sConstraints, 
                                           ViewSchemaConstraints cViewConstraints, ViewSchemaConstraints sViewConstraints) { 
            Debug.Assert(cConstraints.KeyConstraints.Count() == cViewConstraints.KeyConstraints.Count(),
                         "Mismatch in number of C basic and view key constraints"); 
            Debug.Assert(sConstraints.KeyConstraints.Count() == sViewConstraints.KeyConstraints.Count(),
                         "Mismatch in number of S basic and view key constraints");
        }
        #endregion 

        // Keeps track of two extent objects 
        private class ExtentPair { 
            internal ExtentPair(EntitySetBase acExtent, EntitySetBase asExtent) {
                cExtent = acExtent; 
                sExtent = asExtent;
            }
            internal EntitySetBase cExtent;
            internal EntitySetBase sExtent; 

            public override bool Equals(object obj) { 
                if (object.ReferenceEquals(this, obj)) { 
                    return true;
                } 
                ExtentPair pair = obj as ExtentPair;
                if (pair == null) {
                    return false;
                } 

                return pair.cExtent.Equals(cExtent) && pair.sExtent.Equals(sExtent); 
            } 

            public override int GetHashCode() { 
                return cExtent.GetHashCode() ^ sExtent.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