Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / DataEntity / System / Data / Query / PlanCompiler / ConstraintManager.cs / 1 / ConstraintManager.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....], [....] //--------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Globalization; using System.Data.Common; using System.Data.Query.InternalTrees; using md=System.Data.Metadata.Edm; //using System.Diagnostics; // Please use PlanCompiler.Assert instead of Debug.Assert in this class... // // The ConstraintManager module manages foreign key constraints for a query. It reshapes // referential constraints supplied by metadata into a more useful form. // namespace System.Data.Query.PlanCompiler { ////// A simple class that represents a pair of extents /// internal class ExtentPair { #region public surface ////// Return the left component of the pair /// internal md.EntitySetBase Left { get { return m_left; } } ////// Return the right component of the pair /// internal md.EntitySetBase Right { get { return m_right; } } ////// Equals /// /// ///public override bool Equals(object obj) { ExtentPair other = obj as ExtentPair; return (other != null) && other.Left.Equals(this.Left) && other.Right.Equals(this.Right); } /// /// Hashcode /// ///public override int GetHashCode() { return (this.Left.GetHashCode() << 4) ^ this.Right.GetHashCode(); } #endregion #region constructors internal ExtentPair(md.EntitySetBase left, md.EntitySetBase right) { m_left = left; m_right = right; } #endregion #region private state private md.EntitySetBase m_left; private md.EntitySetBase m_right; #endregion } /// /// Information about a foreign-key constraint /// internal class ForeignKeyConstraint { #region public surface ////// Parent key properties /// internal ListParentKeys { get { return m_parentKeys; } } /// /// Child key properties /// internal ListChildKeys { get { return m_childKeys; } } /// /// Get the parent-child pair /// internal ExtentPair Pair { get { return m_extentPair; } } ////// Return the child rowcount /// internal md.RelationshipMultiplicity ChildMultiplicity { get { return m_constraint.ToRole.RelationshipMultiplicity; } } ////// Get the corresponding parent (key) property, for a specific child (foreign key) property /// /// child (foreign key) property name /// corresponding parent property name ///true, if the parent property was found internal bool GetParentProperty(string childPropertyName, out string parentPropertyName) { BuildKeyMap(); return m_keyMap.TryGetValue(childPropertyName, out parentPropertyName); } ////// Hash code /// ///public override int GetHashCode() { return m_extentPair.GetHashCode(); } /// /// Equality check for two FK constraints /// /// the other FK constraint ///true, if they represent the same object public override bool Equals(object obj) { ForeignKeyConstraint other = obj as ForeignKeyConstraint; return other != null && other.m_extentPair.Equals(this.m_extentPair); } #endregion #region constructors internal ForeignKeyConstraint(md.RelationshipType relType, md.RelationshipSet relationshipSet, md.ReferentialConstraint constraint) { md.AssociationSet assocSet = relationshipSet as md.AssociationSet; md.AssociationEndMember fromEnd = constraint.FromRole as md.AssociationEndMember; md.AssociationEndMember toEnd = constraint.ToRole as md.AssociationEndMember; // Currently only Associations are supported if (null == assocSet || null == fromEnd || null == toEnd) { throw EntityUtil.NotSupported(); } m_constraint = constraint; md.EntitySet parent = System.Data.Common.Utils.MetadataHelper.GetEntitySetAtEnd(assocSet, fromEnd);// relationshipSet.GetRelationshipEndExtent(constraint.FromRole); md.EntitySet child = System.Data.Common.Utils.MetadataHelper.GetEntitySetAtEnd(assocSet, toEnd);// relationshipSet.GetRelationshipEndExtent(constraint.ToRole); m_extentPair = new ExtentPair(parent, child); m_childKeys = new List(); foreach (md.EdmProperty prop in constraint.ToProperties) { m_childKeys.Add(prop.Name); } m_parentKeys = new List (); foreach (md.EdmProperty prop in constraint.FromProperties) { m_parentKeys.Add(prop.Name); } PlanCompiler.Assert((md.RelationshipMultiplicity.ZeroOrOne == fromEnd.RelationshipMultiplicity || md.RelationshipMultiplicity.One == fromEnd.RelationshipMultiplicity), "from-end of relationship constraint cannot have multiplicity greater than 1"); } #endregion #region private state private ExtentPair m_extentPair; private List m_parentKeys; private List m_childKeys; private md.ReferentialConstraint m_constraint; private Dictionary m_keyMap; #endregion #region private methods /// /// Build up an equivalence map of primary keys and foreign keys (ie) for each /// foreign key column, identify the corresponding primary key property /// private void BuildKeyMap() { if (m_keyMap != null) { return; } m_keyMap = new Dictionary(); IEnumerator parentProps = m_constraint.FromProperties.GetEnumerator(); IEnumerator childProps = m_constraint.ToProperties.GetEnumerator(); while (true) { bool parentOver = !parentProps.MoveNext(); bool childOver = !childProps.MoveNext(); PlanCompiler.Assert(parentOver == childOver, "key count mismatch"); if (parentOver) { break; } m_keyMap[childProps.Current.Name] = parentProps.Current.Name; } } #endregion } /// /// Keeps track of all foreign key relationships /// internal class ConstraintManager { #region public methods ////// Is there a parent child relationship between table1 and table2 ? /// /// parent table ? /// child table ? /// list of constraints ? ///true if there is at least one constraint internal bool IsParentChildRelationship(md.EntitySetBase table1, md.EntitySetBase table2, out Listconstraints) { LoadRelationships(table1.EntityContainer); LoadRelationships(table2.EntityContainer); ExtentPair extentPair = new ExtentPair(table1, table2); return m_parentChildRelationships.TryGetValue(extentPair, out constraints); } /// /// Load all relationships in this entity container /// /// internal void LoadRelationships(md.EntityContainer entityContainer) { // Check to see if I've already loaded information for this entity container if (m_entityContainerMap.ContainsKey(entityContainer)) { return; } // Load all relationships from this entitycontainer foreach (md.EntitySetBase e in entityContainer.BaseEntitySets) { md.RelationshipSet relationshipSet = e as md.RelationshipSet; if (relationshipSet == null) { continue; } // Relationship sets can only contain relationships md.RelationshipType relationshipType = (md.RelationshipType)relationshipSet.ElementType; md.AssociationType assocType = relationshipType as md.AssociationType; // // Handle only binary Association relationships for now // if (null == assocType || !IsBinary(relationshipType)) { continue; } foreach (md.ReferentialConstraint constraint in assocType.ReferentialConstraints) { ListfkConstraintList; ForeignKeyConstraint fkConstraint = new ForeignKeyConstraint(relationshipType, relationshipSet, constraint); if (!m_parentChildRelationships.TryGetValue(fkConstraint.Pair, out fkConstraintList)) { fkConstraintList = new List (); m_parentChildRelationships[fkConstraint.Pair] = fkConstraintList; } // // Theoretically, we can have more than one fk constraint between // the 2 tables (though, it is unlikely) // fkConstraintList.Add(fkConstraint); } } // Mark this entity container as already loaded m_entityContainerMap[entityContainer] = entityContainer; } #endregion #region constructors internal ConstraintManager() { m_entityContainerMap = new Dictionary (); m_parentChildRelationships = new Dictionary >(); } #endregion #region private state private Dictionary m_entityContainerMap; private Dictionary > m_parentChildRelationships; #endregion #region private methods /// /// Is this relationship a binary relationship (ie) does it have exactly 2 end points? /// /// This should ideally be a method supported by RelationType itself /// /// ///true, if this is a binary relationship private static bool IsBinary(md.RelationshipType relationshipType) { int endCount = 0; foreach(md.EdmMember member in relationshipType.Members) { if (member is md.RelationshipEndMember) { endCount++; if (endCount > 2) { return false; } } } return (endCount == 2); } #endregion } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....], [....] //--------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Globalization; using System.Data.Common; using System.Data.Query.InternalTrees; using md=System.Data.Metadata.Edm; //using System.Diagnostics; // Please use PlanCompiler.Assert instead of Debug.Assert in this class... // // The ConstraintManager module manages foreign key constraints for a query. It reshapes // referential constraints supplied by metadata into a more useful form. // namespace System.Data.Query.PlanCompiler { ////// A simple class that represents a pair of extents /// internal class ExtentPair { #region public surface ////// Return the left component of the pair /// internal md.EntitySetBase Left { get { return m_left; } } ////// Return the right component of the pair /// internal md.EntitySetBase Right { get { return m_right; } } ////// Equals /// /// ///public override bool Equals(object obj) { ExtentPair other = obj as ExtentPair; return (other != null) && other.Left.Equals(this.Left) && other.Right.Equals(this.Right); } /// /// Hashcode /// ///public override int GetHashCode() { return (this.Left.GetHashCode() << 4) ^ this.Right.GetHashCode(); } #endregion #region constructors internal ExtentPair(md.EntitySetBase left, md.EntitySetBase right) { m_left = left; m_right = right; } #endregion #region private state private md.EntitySetBase m_left; private md.EntitySetBase m_right; #endregion } /// /// Information about a foreign-key constraint /// internal class ForeignKeyConstraint { #region public surface ////// Parent key properties /// internal ListParentKeys { get { return m_parentKeys; } } /// /// Child key properties /// internal ListChildKeys { get { return m_childKeys; } } /// /// Get the parent-child pair /// internal ExtentPair Pair { get { return m_extentPair; } } ////// Return the child rowcount /// internal md.RelationshipMultiplicity ChildMultiplicity { get { return m_constraint.ToRole.RelationshipMultiplicity; } } ////// Get the corresponding parent (key) property, for a specific child (foreign key) property /// /// child (foreign key) property name /// corresponding parent property name ///true, if the parent property was found internal bool GetParentProperty(string childPropertyName, out string parentPropertyName) { BuildKeyMap(); return m_keyMap.TryGetValue(childPropertyName, out parentPropertyName); } ////// Hash code /// ///public override int GetHashCode() { return m_extentPair.GetHashCode(); } /// /// Equality check for two FK constraints /// /// the other FK constraint ///true, if they represent the same object public override bool Equals(object obj) { ForeignKeyConstraint other = obj as ForeignKeyConstraint; return other != null && other.m_extentPair.Equals(this.m_extentPair); } #endregion #region constructors internal ForeignKeyConstraint(md.RelationshipType relType, md.RelationshipSet relationshipSet, md.ReferentialConstraint constraint) { md.AssociationSet assocSet = relationshipSet as md.AssociationSet; md.AssociationEndMember fromEnd = constraint.FromRole as md.AssociationEndMember; md.AssociationEndMember toEnd = constraint.ToRole as md.AssociationEndMember; // Currently only Associations are supported if (null == assocSet || null == fromEnd || null == toEnd) { throw EntityUtil.NotSupported(); } m_constraint = constraint; md.EntitySet parent = System.Data.Common.Utils.MetadataHelper.GetEntitySetAtEnd(assocSet, fromEnd);// relationshipSet.GetRelationshipEndExtent(constraint.FromRole); md.EntitySet child = System.Data.Common.Utils.MetadataHelper.GetEntitySetAtEnd(assocSet, toEnd);// relationshipSet.GetRelationshipEndExtent(constraint.ToRole); m_extentPair = new ExtentPair(parent, child); m_childKeys = new List(); foreach (md.EdmProperty prop in constraint.ToProperties) { m_childKeys.Add(prop.Name); } m_parentKeys = new List (); foreach (md.EdmProperty prop in constraint.FromProperties) { m_parentKeys.Add(prop.Name); } PlanCompiler.Assert((md.RelationshipMultiplicity.ZeroOrOne == fromEnd.RelationshipMultiplicity || md.RelationshipMultiplicity.One == fromEnd.RelationshipMultiplicity), "from-end of relationship constraint cannot have multiplicity greater than 1"); } #endregion #region private state private ExtentPair m_extentPair; private List m_parentKeys; private List m_childKeys; private md.ReferentialConstraint m_constraint; private Dictionary m_keyMap; #endregion #region private methods /// /// Build up an equivalence map of primary keys and foreign keys (ie) for each /// foreign key column, identify the corresponding primary key property /// private void BuildKeyMap() { if (m_keyMap != null) { return; } m_keyMap = new Dictionary(); IEnumerator parentProps = m_constraint.FromProperties.GetEnumerator(); IEnumerator childProps = m_constraint.ToProperties.GetEnumerator(); while (true) { bool parentOver = !parentProps.MoveNext(); bool childOver = !childProps.MoveNext(); PlanCompiler.Assert(parentOver == childOver, "key count mismatch"); if (parentOver) { break; } m_keyMap[childProps.Current.Name] = parentProps.Current.Name; } } #endregion } /// /// Keeps track of all foreign key relationships /// internal class ConstraintManager { #region public methods ////// Is there a parent child relationship between table1 and table2 ? /// /// parent table ? /// child table ? /// list of constraints ? ///true if there is at least one constraint internal bool IsParentChildRelationship(md.EntitySetBase table1, md.EntitySetBase table2, out Listconstraints) { LoadRelationships(table1.EntityContainer); LoadRelationships(table2.EntityContainer); ExtentPair extentPair = new ExtentPair(table1, table2); return m_parentChildRelationships.TryGetValue(extentPair, out constraints); } /// /// Load all relationships in this entity container /// /// internal void LoadRelationships(md.EntityContainer entityContainer) { // Check to see if I've already loaded information for this entity container if (m_entityContainerMap.ContainsKey(entityContainer)) { return; } // Load all relationships from this entitycontainer foreach (md.EntitySetBase e in entityContainer.BaseEntitySets) { md.RelationshipSet relationshipSet = e as md.RelationshipSet; if (relationshipSet == null) { continue; } // Relationship sets can only contain relationships md.RelationshipType relationshipType = (md.RelationshipType)relationshipSet.ElementType; md.AssociationType assocType = relationshipType as md.AssociationType; // // Handle only binary Association relationships for now // if (null == assocType || !IsBinary(relationshipType)) { continue; } foreach (md.ReferentialConstraint constraint in assocType.ReferentialConstraints) { ListfkConstraintList; ForeignKeyConstraint fkConstraint = new ForeignKeyConstraint(relationshipType, relationshipSet, constraint); if (!m_parentChildRelationships.TryGetValue(fkConstraint.Pair, out fkConstraintList)) { fkConstraintList = new List (); m_parentChildRelationships[fkConstraint.Pair] = fkConstraintList; } // // Theoretically, we can have more than one fk constraint between // the 2 tables (though, it is unlikely) // fkConstraintList.Add(fkConstraint); } } // Mark this entity container as already loaded m_entityContainerMap[entityContainer] = entityContainer; } #endregion #region constructors internal ConstraintManager() { m_entityContainerMap = new Dictionary (); m_parentChildRelationships = new Dictionary >(); } #endregion #region private state private Dictionary m_entityContainerMap; private Dictionary > m_parentChildRelationships; #endregion #region private methods /// /// Is this relationship a binary relationship (ie) does it have exactly 2 end points? /// /// This should ideally be a method supported by RelationType itself /// /// ///true, if this is a binary relationship private static bool IsBinary(md.RelationshipType relationshipType) { int endCount = 0; foreach(md.EdmMember member in relationshipType.Members) { if (member is md.RelationshipEndMember) { endCount++; if (endCount > 2) { return false; } } } return (endCount == 2); } #endregion } } // 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
- IDataContractSurrogate.cs
- DataObjectFieldAttribute.cs
- Image.cs
- EntityDataSourceChangedEventArgs.cs
- MDIClient.cs
- UnsafeMethods.cs
- OleDbRowUpdatingEvent.cs
- PropertyBuilder.cs
- DetailsViewUpdateEventArgs.cs
- ShaperBuffers.cs
- XPathDescendantIterator.cs
- LogExtent.cs
- LifetimeServices.cs
- ServiceChannelFactory.cs
- MobileDeviceCapabilitiesSectionHandler.cs
- FontUnitConverter.cs
- Membership.cs
- UnsafeNativeMethodsCLR.cs
- Delegate.cs
- CodeDomSerializerBase.cs
- DependencyObjectPropertyDescriptor.cs
- GeneralTransform3DGroup.cs
- ExpressionPrinter.cs
- PresentationSource.cs
- DataStreams.cs
- DiscoveryClientChannelBase.cs
- QueueProcessor.cs
- HtmlUtf8RawTextWriter.cs
- DesignerOptions.cs
- UnmanagedMarshal.cs
- WindowsClaimSet.cs
- unitconverter.cs
- SoapAttributes.cs
- DataView.cs
- HtmlInputImage.cs
- OleDbPropertySetGuid.cs
- PersistNameAttribute.cs
- ZeroOpNode.cs
- ToolStrip.cs
- followingsibling.cs
- ResourceExpressionBuilder.cs
- RedistVersionInfo.cs
- SimpleWebHandlerParser.cs
- DiscreteKeyFrames.cs
- LinkUtilities.cs
- IApplicationTrustManager.cs
- LoginName.cs
- XmlDataProvider.cs
- IisTraceWebEventProvider.cs
- Formatter.cs
- WebPartConnectionsCloseVerb.cs
- DataBindingExpressionBuilder.cs
- GenericsInstances.cs
- DataGridBoolColumn.cs
- MatrixTransform3D.cs
- SchemaCollectionCompiler.cs
- FactoryGenerator.cs
- DataServiceRequest.cs
- Selector.cs
- MissingManifestResourceException.cs
- DataSourceHelper.cs
- RoleManagerSection.cs
- LinkDescriptor.cs
- MinMaxParagraphWidth.cs
- PropertyTab.cs
- ProcessModelSection.cs
- ToolStripDropDownButton.cs
- ApplyImportsAction.cs
- AppSecurityManager.cs
- InstallerTypeAttribute.cs
- ConsoleTraceListener.cs
- QuaternionKeyFrameCollection.cs
- SchemaTableColumn.cs
- WpfWebRequestHelper.cs
- HotSpotCollection.cs
- TemplateInstanceAttribute.cs
- XsdDataContractImporter.cs
- XmlReflectionImporter.cs
- RSAPKCS1KeyExchangeDeformatter.cs
- DataGridColumnStyleMappingNameEditor.cs
- AccessedThroughPropertyAttribute.cs
- MetadataUtil.cs
- SafeFileMappingHandle.cs
- MouseOverProperty.cs
- WebServiceTypeData.cs
- Vector3D.cs
- StylusCaptureWithinProperty.cs
- TaskFileService.cs
- OdbcConnectionFactory.cs
- CollectionsUtil.cs
- DataSysAttribute.cs
- DataMemberAttribute.cs
- TransformProviderWrapper.cs
- ComboBoxHelper.cs
- Margins.cs
- RegexReplacement.cs
- StrongNamePublicKeyBlob.cs
- Guid.cs
- ApplicationTrust.cs
- PageThemeBuildProvider.cs