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
- SQLBoolean.cs
- JsonWriter.cs
- TransactionBridgeSection.cs
- MetadataCache.cs
- SqlUserDefinedAggregateAttribute.cs
- StateWorkerRequest.cs
- SecuritySessionServerSettings.cs
- ToolStripDesignerUtils.cs
- ScriptResourceAttribute.cs
- KeyGestureConverter.cs
- LifetimeServices.cs
- BaseWebProxyFinder.cs
- XmlReaderDelegator.cs
- Rect3D.cs
- CompilerResults.cs
- ThreadStaticAttribute.cs
- WebReferencesBuildProvider.cs
- SelectionChangedEventArgs.cs
- FamilyMap.cs
- WindowsEditBox.cs
- IgnoreSection.cs
- DrawItemEvent.cs
- GraphicsPathIterator.cs
- ScopelessEnumAttribute.cs
- ReferencedAssembly.cs
- SQLBoolean.cs
- PointKeyFrameCollection.cs
- CssTextWriter.cs
- RectangleGeometry.cs
- ipaddressinformationcollection.cs
- DataBindingHandlerAttribute.cs
- LassoHelper.cs
- Decoder.cs
- ClientUtils.cs
- DbConnectionInternal.cs
- Request.cs
- IRCollection.cs
- AssemblyResourceLoader.cs
- Vector3DCollectionConverter.cs
- CqlParserHelpers.cs
- InvalidateEvent.cs
- StreamHelper.cs
- SubclassTypeValidator.cs
- ErrorActivity.cs
- TransformValueSerializer.cs
- ImagingCache.cs
- KeyPullup.cs
- BitmapEffectGroup.cs
- SqlMethods.cs
- MessageSecurityOverTcpElement.cs
- TextEffectCollection.cs
- PropertyInfoSet.cs
- VirtualPathProvider.cs
- ExceptionCollection.cs
- LinkUtilities.cs
- SqlNodeTypeOperators.cs
- WebPartUtil.cs
- CaseInsensitiveOrdinalStringComparer.cs
- FileDataSourceCache.cs
- ZoneButton.cs
- ImageIndexConverter.cs
- TypeToStringValueConverter.cs
- TrustSection.cs
- FrameworkName.cs
- ActivityDesignerHighlighter.cs
- TrailingSpaceComparer.cs
- UIElementHelper.cs
- WebPartConnectionsEventArgs.cs
- ResolveNameEventArgs.cs
- SecurityPermission.cs
- SyndicationElementExtension.cs
- DesignerSerializationOptionsAttribute.cs
- _Events.cs
- ToolStripArrowRenderEventArgs.cs
- Debug.cs
- CannotUnloadAppDomainException.cs
- RuleConditionDialog.Designer.cs
- CodeIdentifiers.cs
- ModelItemDictionaryImpl.cs
- XPathDescendantIterator.cs
- XmlSerializerVersionAttribute.cs
- WebPart.cs
- CallbackValidatorAttribute.cs
- ValidatorCompatibilityHelper.cs
- UriScheme.cs
- UIElement3D.cs
- DocumentXmlWriter.cs
- CharAnimationBase.cs
- EntityDesignPluralizationHandler.cs
- SpellerHighlightLayer.cs
- Models.cs
- HttpWrapper.cs
- SqlDataSourceFilteringEventArgs.cs
- SizeChangedInfo.cs
- HostingPreferredMapPath.cs
- RegionIterator.cs
- PeerApplication.cs
- OdbcConnectionPoolProviderInfo.cs
- ContextBase.cs
- Form.cs