Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Map / ViewGeneration / Structures / LeafCellTreeNode.cs / 1305376 / LeafCellTreeNode.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System.Collections.Generic; using System.Data.Common.Utils; using System.Data.Mapping.ViewGeneration.CqlGeneration; using System.Data.Mapping.ViewGeneration.QueryRewriting; using System.Linq; using System.Text; using System.Diagnostics; using System.Data.Metadata.Edm; namespace System.Data.Mapping.ViewGeneration.Structures { // This class represents the nodes that reside at the leaves of the tree internal class LeafCellTreeNode : CellTreeNode { #region Constructor // effects: Encapsulate the cell wrapper in the node internal LeafCellTreeNode(ViewgenContext context, LeftCellWrapper cellWrapper) : base(context) { m_cellWrapper = cellWrapper; m_leftFragmentQuery = cellWrapper.FragmentQuery; cellWrapper.AssertHasUniqueCell(); m_rightFragmentQuery = FragmentQuery.Create( cellWrapper.OriginalCellNumberString, cellWrapper.CreateRoleBoolean(), cellWrapper.RightCellQuery); } internal LeafCellTreeNode(ViewgenContext context, LeftCellWrapper cellWrapper, FragmentQuery rightFragmentQuery) : base(context) { m_cellWrapper = cellWrapper; m_leftFragmentQuery = cellWrapper.FragmentQuery; m_rightFragmentQuery = rightFragmentQuery; } #endregion #region Fields internal static readonly IEqualityComparerEqualityComparer = new LeafCellTreeNodeComparer(); // The cell at the leaf level private LeftCellWrapper m_cellWrapper; private FragmentQuery m_leftFragmentQuery; private FragmentQuery m_rightFragmentQuery; #endregion #region Properties internal LeftCellWrapper LeftCellWrapper { get { return m_cellWrapper; } } internal override MemberDomainMap RightDomainMap { get { return m_cellWrapper.RightDomainMap; } } // effects: See CellTreeNode.FragmentQuery internal override FragmentQuery LeftFragmentQuery { get { return m_cellWrapper.FragmentQuery; } } internal override FragmentQuery RightFragmentQuery { get { Debug.Assert(m_rightFragmentQuery != null, "Unassigned right fragment query"); return m_rightFragmentQuery; } } // effects: See CellTreeNode.Attributes internal override Set Attributes { get { return m_cellWrapper.Attributes; } } // effects: See CellTreeNode.Children internal override List Children { get { return new List (); } } // effects: See CellTreeNode.OpType internal override CellTreeOpType OpType { get { return CellTreeOpType.Leaf; } } internal override int NumProjectedSlots { get { return LeftCellWrapper.RightCellQuery.NumProjectedSlots; } } internal override int NumBoolSlots { get { return LeftCellWrapper.RightCellQuery.NumBoolVars; } } #endregion #region Methods internal override TOutput Accept (CellTreeVisitor visitor, TInput param) { return visitor.VisitLeaf(this, param); } internal override TOutput Accept (SimpleCellTreeVisitor visitor, TInput param) { return visitor.VisitLeaf(this, param); } internal override bool IsProjectedSlot(int slot) { CellQuery cellQuery = LeftCellWrapper.RightCellQuery; if (IsBoolSlot(slot)) { return cellQuery.GetBoolVar(SlotToBoolIndex(slot)) != null; } else { return cellQuery.ProjectedSlotAt(slot) != null; } } #endregion #region Leaf CqlBlock Methods internal override CqlBlock ToCqlBlock(bool[] requiredSlots, CqlIdentifiers identifiers, ref int blockAliasNum, ref List withStatements) { // Get the projected slots and the boolean expressions int totalSlots = requiredSlots.Length; CellQuery cellQuery = LeftCellWrapper.RightCellQuery; SlotInfo[] projectedSlots = new SlotInfo[totalSlots]; Debug.Assert(cellQuery.NumProjectedSlots + cellQuery.NumBoolVars == totalSlots, "Wrong number of projected slots in node"); Debug.Assert(cellQuery.NumProjectedSlots == ProjectedSlotMap.Count, "Different number of slots in cell query and what we have mappings for"); // Add the regular fields for (int i = 0; i < cellQuery.NumProjectedSlots; i++) { ProjectedSlot slot = cellQuery.ProjectedSlotAt(i); // If the slot is not null, we will project it // For extents, we say that all requiredlots are the only the // ones that are CLR non-null. Recall that "real" nulls are // handled by having a CellConstant.Null in ConstantSlot if (requiredSlots[i] && slot == null) { ConstantProjectedSlot defaultValue = new ConstantProjectedSlot(Domain.GetDefaultValueForMemberPath(ProjectedSlotMap[i], GetLeaves(), ViewgenContext.Config)); cellQuery.FixMissingSlotAsDefaultConstant(i, defaultValue); slot = defaultValue; } SlotInfo slotInfo = new SlotInfo(requiredSlots[i], slot != null, slot, ProjectedSlotMap[i]); projectedSlots[i] = slotInfo; } // Add the boolean fields for (int boolNum = 0; boolNum < cellQuery.NumBoolVars; boolNum++) { BoolExpression expr = cellQuery.GetBoolVar(boolNum); BooleanProjectedSlot boolSlot; if (expr != null) { boolSlot = new BooleanProjectedSlot(expr, identifiers, boolNum); } else { boolSlot = new BooleanProjectedSlot(BoolExpression.False, identifiers, boolNum); } int slotIndex = BoolIndexToSlot(boolNum); SlotInfo slotInfo = new SlotInfo(requiredSlots[slotIndex], expr != null, boolSlot, null); projectedSlots[slotIndex] = slotInfo; } //See if we are generating a query view and whether there are any colocated foreign keys for which //we have to add With statements IEnumerable totalProjectedSlots = projectedSlots; if ((cellQuery.Extent.EntityContainer.DataSpace == DataSpace.SSpace) && (this.m_cellWrapper.LeftExtent.BuiltInTypeKind == BuiltInTypeKind.EntitySet)) { IEnumerable associationSetMaps = this.ViewgenContext.EntityContainerMapping.GetRelationshipSetMappingsFor(this.m_cellWrapper.LeftExtent, cellQuery.Extent); List foreignKeySlots = new List (); foreach (StorageAssociationSetMapping colocatedAssociationSetMap in associationSetMaps) { WithStatement withStatement; if (TryGetWithStatement(colocatedAssociationSetMap, this.m_cellWrapper.LeftExtent, cellQuery.SourceExtentMemberPath, ref foreignKeySlots, out withStatement)) { withStatements.Add(withStatement); totalProjectedSlots = projectedSlots.Concat(foreignKeySlots); } } } ExtentCqlBlock result = new ExtentCqlBlock(cellQuery.Extent, cellQuery.SelectDistinctFlag, totalProjectedSlots.ToArray(), cellQuery.WhereClause, identifiers, ++blockAliasNum); return result; } private bool TryGetWithStatement(StorageAssociationSetMapping colocatedAssociationSetMap, EntitySetBase thisExtent, MemberPath sRootNode, ref List foreignKeySlots, out WithStatement withStatement) { Debug.Assert(foreignKeySlots != null); withStatement = null; //Get the map for foreign key end StorageEndPropertyMapping foreignKeyEndMap = GetForeignKeyEndMapFromAssocitionMap(colocatedAssociationSetMap, thisExtent); if ((foreignKeyEndMap == null) || (foreignKeyEndMap.EndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)) { return false; } //Collect the member paths for edm scalar properties that are part of the end mapping //These will be used as part of With Statement List associationEndMemberPaths = new List (); //Get the member path for AssociationSet AssociationSet associationSet = (AssociationSet)colocatedAssociationSetMap.Set; MemberPath prefix = new MemberPath(associationSet, foreignKeyEndMap.EndMember); //Get the key properties from edm type since the query parser depends on the order of key members EntityTypeBase edmEntityType = ((RefType)(foreignKeyEndMap.EndMember.TypeUsage.EdmType)).ElementType; IEnumerable propertyMaps = foreignKeyEndMap.Properties.Cast (); foreach (EdmProperty edmProperty in edmEntityType.KeyMembers) { IEnumerable scalarPropertyMaps = propertyMaps.Where(propMap => (propMap.EdmProperty.Equals(edmProperty))); Debug.Assert(scalarPropertyMaps.Count() == 1, "Can't Map the same column multiple times in the same end"); StorageScalarPropertyMapping scalarPropertyMap = scalarPropertyMaps.First(); //Create SlotInfo for Freign Key member that needs to be projected MemberProjectedSlot sSlot = new MemberProjectedSlot(new MemberPath(sRootNode, scalarPropertyMap.ColumnProperty)); MemberPath endMemberKeyPath = new MemberPath(prefix, edmProperty); associationEndMemberPaths.Add(endMemberKeyPath); foreignKeySlots.Add(new SlotInfo(true, true, sSlot, endMemberKeyPath)); } //Now create the With Statement with all the needed info like ToEntitySet, AssociationSet, FromRoleName, ToRoleName EntitySet refEntitySet = MetadataHelper.GetEntitySetAtEnd(associationSet, (AssociationEndMember)(foreignKeyEndMap.EndMember)); AssociationEndMember fromEnd = MetadataHelper.GetOtherAssociationEnd((AssociationEndMember)(foreignKeyEndMap.EndMember)); EntityType endEntityType = (EntityType)(((RefType)foreignKeyEndMap.EndMember.TypeUsage.EdmType).ElementType); EntityType fromEndEntityType = (EntityType)(((RefType)fromEnd.TypeUsage.EdmType).ElementType); //parent assignable from child: Ensures they are in the same hierarchy if (!thisExtent.ElementType.IsAssignableFrom(fromEndEntityType)) { return false; } withStatement = new WithStatement(refEntitySet, endEntityType, fromEndEntityType, associationSet, fromEnd.Name, foreignKeyEndMap.EndMember.Name, associationEndMemberPaths); return true; } //Gets the end that is not mapped to the primary key of the table private StorageEndPropertyMapping GetForeignKeyEndMapFromAssocitionMap(StorageAssociationSetMapping colocatedAssociationSetMap, EntitySetBase thisExtent) { StorageMappingFragment mapFragment = colocatedAssociationSetMap.TypeMappings.First().MappingFragments.First(); EntitySet storeEntitySet = (EntitySet)(colocatedAssociationSetMap.StoreEntitySet); IEnumerable keyProperties = storeEntitySet.ElementType.KeyMembers; //Find the end that's mapped to primary key foreach (StorageEndPropertyMapping endMap in mapFragment.Properties) { IEnumerable endStoreMembers = endMap.StoreProperties; if (endStoreMembers.SequenceEqual(keyProperties, EqualityComparer .Default)) { //Return the map for the other end since that is the foreign key end IEnumerable otherEnds = mapFragment.Properties.OfType ().Where(eMap => (!eMap.Equals(endMap))); Debug.Assert(otherEnds.Count() == 1); return otherEnds.First(); } } //This is probably defensive, but there should be no problem in falling back on the //AssociationSetMap if colocated foreign key is not found for some reason. return null; } #endregion #region String Methods // effects: See CellTreeNode.ToString internal override void ToCompactString(StringBuilder stringBuilder) { m_cellWrapper.ToCompactString(stringBuilder); } #endregion #region IEqualityComparer // A comparer that equates leaf nodes if the wrapper is the same private class LeafCellTreeNodeComparer : IEqualityComparer { public bool Equals(LeafCellTreeNode left, LeafCellTreeNode right) { // Quick check with references if (object.ReferenceEquals(left, right)) { // Gets the Null and Undefined case as well return true; } // One of them is non-null at least if (left == null || right == null) { return false; } // Both are non-null at this point return left.m_cellWrapper.Equals(right.m_cellWrapper); } public int GetHashCode(LeafCellTreeNode node) { return node.m_cellWrapper.GetHashCode(); } } #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
- SecurityTokenRequirement.cs
- DateTimeConverter.cs
- RotationValidation.cs
- SqlUtils.cs
- HttpWebRequest.cs
- MemberExpressionHelper.cs
- DataGridTextBox.cs
- Splitter.cs
- MergePropertyDescriptor.cs
- DataGridViewLinkCell.cs
- Assert.cs
- MeasurementDCInfo.cs
- SqlDataSourceWizardForm.cs
- LoadedOrUnloadedOperation.cs
- UrlMappingsSection.cs
- Point.cs
- ToolStripItemCollection.cs
- TransformerInfo.cs
- GlobalProxySelection.cs
- SqlTypeConverter.cs
- PropagatorResult.cs
- LostFocusEventManager.cs
- GridViewAutomationPeer.cs
- DataBindingExpressionBuilder.cs
- ConfigurationSchemaErrors.cs
- Base64Stream.cs
- MaskInputRejectedEventArgs.cs
- UpdateTracker.cs
- PreservationFileWriter.cs
- DataListAutoFormat.cs
- FilterException.cs
- mediaeventshelper.cs
- StrokeRenderer.cs
- List.cs
- AsymmetricKeyExchangeDeformatter.cs
- ClrPerspective.cs
- AnnotationResource.cs
- GC.cs
- UInt64Converter.cs
- BindingWorker.cs
- SmtpSection.cs
- ImageResources.Designer.cs
- StrokeNodeOperations.cs
- DataSvcMapFileSerializer.cs
- PropertySourceInfo.cs
- XPathChildIterator.cs
- PointF.cs
- DatatypeImplementation.cs
- StatusBar.cs
- HighlightComponent.cs
- WinCategoryAttribute.cs
- ClientFormsIdentity.cs
- TrustLevel.cs
- BitmapCacheBrush.cs
- PrinterResolution.cs
- UpdateInfo.cs
- ConfigurationPropertyAttribute.cs
- XAMLParseException.cs
- Contracts.cs
- WaveHeader.cs
- ValidationRuleCollection.cs
- ManagementPath.cs
- Int16KeyFrameCollection.cs
- MessageSecurityVersionConverter.cs
- ExtensibleClassFactory.cs
- PageBreakRecord.cs
- Control.cs
- DefaultHttpHandler.cs
- SqlEnums.cs
- CompoundFileDeflateTransform.cs
- Funcletizer.cs
- HMACSHA256.cs
- Encoder.cs
- WebPartConnectionsDisconnectVerb.cs
- RoutedCommand.cs
- ClientSettingsSection.cs
- XmlCharCheckingWriter.cs
- TextHidden.cs
- Part.cs
- CFStream.cs
- DiagnosticTraceSource.cs
- ConfigPathUtility.cs
- SafeProcessHandle.cs
- ParallelEnumerableWrapper.cs
- UrlAuthFailedErrorFormatter.cs
- ApplicationServiceManager.cs
- EndpointConfigContainer.cs
- AnimationLayer.cs
- DeferredSelectedIndexReference.cs
- NavigatorInput.cs
- Path.cs
- QualifiedCellIdBoolean.cs
- HttpStreamXmlDictionaryWriter.cs
- StreamInfo.cs
- ExternalException.cs
- ChildrenQuery.cs
- ListViewItem.cs
- Roles.cs
- ReachPageContentCollectionSerializerAsync.cs
- DbMetaDataColumnNames.cs