Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Map / ViewGeneration / Validator.cs / 1305376 / 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 CellGroupValidator { #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 CellGroupValidator(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() { // Check for errors not checked by "C-implies-S principle" if (m_config.IsValidationEnabled) { if (PerformSingleCellChecks() == false) { return m_errorLog; } } else //Note that Metadata loading guarantees that DISTINCT flag is not present { // when update views (and validation) is disabled if (CheckCellsWithDistinctFlag() == 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); 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 if (m_config.IsValidationEnabled) { CheckImplication(m_cViewConstraints, m_sViewConstraints); } 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) { // 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); PopulateBaseConstraints(sCellRelation, sConstraints); 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) { // Populate key constraints baseRelation.PopulateKeyConstraints(constraints); } #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) { // Check key constraints // i.e., if S has a key | , C must have a key that is a subset of this CheckImplicationKeyConstraints(cViewConstraints, sViewConstraints); // 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)); } } } // effects: Checks for key constraint implication problems from // leftViewConstraints to rightViewConstraints. Adds errors/warning to m_errorLog private void CheckImplicationKeyConstraints(ViewSchemaConstraints leftViewConstraints, ViewSchemaConstraints rightViewConstraints) { // 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)); } } } #endregion #region Miscellaneous checks /// /// Checks that if a DISTINCT operator exists between some C-Extent and S-Extent, there are no additional /// mapping fragments between that C-Extent and S-Extent. /// We need to enforce this because DISTINCT is not understood by viewgen machinery, and two fragments may be merged /// despite one of them having DISTINCT. /// private bool CheckCellsWithDistinctFlag() { int errorLogSize = m_errorLog.Count; foreach (Cell cell in m_cells) { if (cell.SQuery.SelectDistinctFlag == CellQuery.SelectDistinct.Yes) { var cExtent = cell.CQuery.Extent; var sExtent = cell.SQuery.Extent; //There should be no other fragments mapping cExtent to sExtent var mapepdFragments = m_cells.Where(otherCell => otherCell != cell) .Where(otherCell => otherCell.CQuery.Extent == cExtent && otherCell.SQuery.Extent == sExtent); if (mapepdFragments.Any()) { var cellsToReport = Enumerable.Union(Enumerable.Repeat(cell, 1), mapepdFragments); ErrorLog.Record record = new ErrorLog.Record(true, ViewGenErrorCode.MultipleFragmentsBetweenCandSExtentWithDistinct, Strings.Viewgen_MultipleFragmentsBetweenCandSExtentWithDistinct(cExtent.Name, sExtent.Name), cellsToReport, String.Empty); m_errorLog.AddEntry(record); } } } return m_errorLog.Count == errorLogSize; } // 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) { // 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, m_cells.Where(c=> c.SQuery.Extent is AssociationSet)); if (error != null) { m_errorLog.AddEntry(error); } error = cell.SQuery.CheckForProjectedNotNullSlots(cell, m_cells.Where(c => c.CQuery.Extent is AssociationSet)); 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 CellGroupValidator { #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 CellGroupValidator(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() { // Check for errors not checked by "C-implies-S principle" if (m_config.IsValidationEnabled) { if (PerformSingleCellChecks() == false) { return m_errorLog; } } else //Note that Metadata loading guarantees that DISTINCT flag is not present { // when update views (and validation) is disabled if (CheckCellsWithDistinctFlag() == 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); 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 if (m_config.IsValidationEnabled) { CheckImplication(m_cViewConstraints, m_sViewConstraints); } 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) { // 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); PopulateBaseConstraints(sCellRelation, sConstraints); 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) { // Populate key constraints baseRelation.PopulateKeyConstraints(constraints); } #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) { // Check key constraints // i.e., if S has a key | , C must have a key that is a subset of this CheckImplicationKeyConstraints(cViewConstraints, sViewConstraints); // 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)); } } } // effects: Checks for key constraint implication problems from // leftViewConstraints to rightViewConstraints. Adds errors/warning to m_errorLog private void CheckImplicationKeyConstraints(ViewSchemaConstraints leftViewConstraints, ViewSchemaConstraints rightViewConstraints) { // 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)); } } } #endregion #region Miscellaneous checks /// /// Checks that if a DISTINCT operator exists between some C-Extent and S-Extent, there are no additional /// mapping fragments between that C-Extent and S-Extent. /// We need to enforce this because DISTINCT is not understood by viewgen machinery, and two fragments may be merged /// despite one of them having DISTINCT. /// private bool CheckCellsWithDistinctFlag() { int errorLogSize = m_errorLog.Count; foreach (Cell cell in m_cells) { if (cell.SQuery.SelectDistinctFlag == CellQuery.SelectDistinct.Yes) { var cExtent = cell.CQuery.Extent; var sExtent = cell.SQuery.Extent; //There should be no other fragments mapping cExtent to sExtent var mapepdFragments = m_cells.Where(otherCell => otherCell != cell) .Where(otherCell => otherCell.CQuery.Extent == cExtent && otherCell.SQuery.Extent == sExtent); if (mapepdFragments.Any()) { var cellsToReport = Enumerable.Union(Enumerable.Repeat(cell, 1), mapepdFragments); ErrorLog.Record record = new ErrorLog.Record(true, ViewGenErrorCode.MultipleFragmentsBetweenCandSExtentWithDistinct, Strings.Viewgen_MultipleFragmentsBetweenCandSExtentWithDistinct(cExtent.Name, sExtent.Name), cellsToReport, String.Empty); m_errorLog.AddEntry(record); } } } return m_errorLog.Count == errorLogSize; } // 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) { // 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, m_cells.Where(c=> c.SQuery.Extent is AssociationSet)); if (error != null) { m_errorLog.AddEntry(error); } error = cell.SQuery.CheckForProjectedNotNullSlots(cell, m_cells.Where(c => c.CQuery.Extent is AssociationSet)); 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
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DiffuseMaterial.cs
- StringDictionary.cs
- SrgsSubset.cs
- ObjectManager.cs
- NameScopePropertyAttribute.cs
- DataListItemCollection.cs
- SymmetricKeyWrap.cs
- XmlProcessingInstruction.cs
- FontUnit.cs
- WebPartZoneCollection.cs
- SafeSecurityHandles.cs
- Table.cs
- DataGridViewDataConnection.cs
- LinkedResourceCollection.cs
- ObjectItemAssemblyLoader.cs
- SplayTreeNode.cs
- ManipulationDelta.cs
- ConstructorNeedsTagAttribute.cs
- BaseAppDomainProtocolHandler.cs
- codemethodreferenceexpression.cs
- BuildResultCache.cs
- Label.cs
- PersonalizationStateQuery.cs
- SoapIncludeAttribute.cs
- TabControl.cs
- KeyEvent.cs
- NotificationContext.cs
- XsltQilFactory.cs
- HtmlContainerControl.cs
- CultureSpecificStringDictionary.cs
- IgnoreSection.cs
- HWStack.cs
- CanExecuteRoutedEventArgs.cs
- DeclarativeCatalogPart.cs
- ViewGenResults.cs
- HtmlInputHidden.cs
- DecimalConverter.cs
- SpellerInterop.cs
- WebPartDisplayModeCancelEventArgs.cs
- GridViewRowCollection.cs
- CriticalFinalizerObject.cs
- BaseAutoFormat.cs
- PartitionerQueryOperator.cs
- CqlGenerator.cs
- ListenerBinder.cs
- OracleCommandBuilder.cs
- ImageMapEventArgs.cs
- DateTimeConverter.cs
- NTAccount.cs
- ContactManager.cs
- XmlCodeExporter.cs
- MarginCollapsingState.cs
- Command.cs
- StringHelper.cs
- FixedTextPointer.cs
- SimpleWorkerRequest.cs
- StandardRuntimeEnumValidator.cs
- FlowDocumentPageViewerAutomationPeer.cs
- X509CertificateCollection.cs
- XpsS0ValidatingLoader.cs
- DateTimeOffset.cs
- CompiledIdentityConstraint.cs
- MetadataSection.cs
- SchemaTableColumn.cs
- FunctionMappingTranslator.cs
- SqlCommandBuilder.cs
- TablePattern.cs
- ScriptResourceHandler.cs
- DateTimeFormatInfoScanner.cs
- ForeignKeyFactory.cs
- RadioButtonBaseAdapter.cs
- PerformanceCounterPermissionEntry.cs
- UnaryQueryOperator.cs
- OdbcConnectionOpen.cs
- TagMapCollection.cs
- JsonFormatWriterGenerator.cs
- PerspectiveCamera.cs
- SoapDocumentServiceAttribute.cs
- WebRequestModuleElementCollection.cs
- MessageVersion.cs
- XmlWellformedWriter.cs
- FormViewModeEventArgs.cs
- ReflectEventDescriptor.cs
- ValueConversionAttribute.cs
- CatalogPartChrome.cs
- TextRunTypographyProperties.cs
- Label.cs
- VirtualizingStackPanel.cs
- ContainerCodeDomSerializer.cs
- LoadedEvent.cs
- ContainerControl.cs
- StandardCommands.cs
- ManagementOptions.cs
- BaseResourcesBuildProvider.cs
- AutomationPatternInfo.cs
- SmiRecordBuffer.cs
- AsymmetricAlgorithm.cs
- WizardStepBase.cs
- RecognitionResult.cs
- MissingFieldException.cs