Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataEntity / System / Data / Map / ViewGeneration / Structures / MemberDomainMap.cs / 3 / MemberDomainMap.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System.Data.Common.Utils; using System.Collections.Generic; using System.Text; using System.Diagnostics; using System.Data.Mapping.ViewGeneration.Utils; using System.Data.Metadata.Edm; using System.Linq; namespace System.Data.Mapping.ViewGeneration.Structures { using CellConstantSet = Set; // This class keeps track of the domain values of the different members // in a schema. E.g., for a discriminator, it keeps track of "P", // "C"; for type of Person, it keeps track of Person, Customer, etc // It exposes two concepts -- the domain of a member variable and the // different possible values for that member, e.g., the possible values // could be 3, 4, 5 but the domain could be 3, 4 (domain is always a // subset of possibleVales internal class MemberDomainMap : InternalBase { #region Constructor private MemberDomainMap(Dictionary domainMap, Dictionary nonConditionDomainMap, MetadataWorkspace workspace) { m_domainMap = domainMap; m_workspace = workspace; m_nonConditionDomainMap = nonConditionDomainMap; } // effects: Creates a map with all the condition member constants // from extentCells. viewtarget determines whether the view is an // update or query view internal MemberDomainMap(ViewTarget viewTarget, IEnumerable extentCells, MetadataWorkspace workspace, ConfigViewGenerator config, Dictionary | > inheritanceGraph) { m_domainMap = new Dictionary (MemberPath.EqualityComparer); m_workspace = workspace; Dictionary domainMap = null; if (viewTarget == ViewTarget.UpdateView) { domainMap = CellConstantDomain.ComputeConstantDomainSetsForSlotsInUpdateViews(extentCells, workspace); } else { domainMap = CellConstantDomain.ComputeConstantDomainSetsForSlotsInQueryViews(extentCells, workspace); } foreach (Cell cell in extentCells) { CellQuery cellQuery = cell.GetLeftQuery(viewTarget); // Get the atoms from cellQuery and only keep the ones that // are condition members foreach (OneOfConst condition in cellQuery.GetConjunctsFromWhereClause()) { // Note: TypeConditions are created using OneOfTypeConst and // scalars are created using OneOfScalarConst MemberPath memberPath = condition.Slot.MemberPath; if (m_domainMap.ContainsKey(memberPath)) { continue; } Debug.Assert(condition is OneOfScalarConst || condition is OneOfTypeConst, "Unexpected OneOfConst"); // Take the narrowed domain from domainMap, if any CellConstantSet domainValues; if (!domainMap.TryGetValue(memberPath, out domainValues)) { domainValues = CellConstantDomain.CreateDomainSetFromMemberPath(memberPath, m_workspace); } //Don't count conditions that are satisfied through IsNull=false if (!domainValues.Contains(CellConstant.NotNull)) { //multiple values of condition represent disjunction in conditions (not currently supported) // if there is any condition constant that is NotNull if(condition.Values.Values.All(conditionConstant => (conditionConstant.Equals(CellConstant.NotNull)) )) { continue; } //else there is atleast one condition value that is allowed, continue view generation } //IsNull condition on a member that is non nullable is an invalid condition if (domainValues.Count <= 0 || (!domainValues.Contains(CellConstant.Null) && condition.Values.Values.Contains(CellConstant.Null))) { string message = System.Data.Entity.Strings.ViewGen_InvalidCondition_0(memberPath.PathToString(false)); ErrorLog.Record record = new ErrorLog.Record(true, ViewGenErrorCode.InvalidCondition, message, cell, String.Empty); ExceptionHelpers.ThrowMappingException(record, config); } if (memberPath.IsAlwaysDefined(inheritanceGraph) == false) { domainValues.Add(CellConstant.Undefined); } AddToDomainMap(memberPath, domainValues); } } // Fill up the domains for the remaining slots as well m_nonConditionDomainMap = new Dictionary (MemberPath.EqualityComparer); foreach (Cell cell in extentCells) { CellQuery cellQuery = cell.GetLeftQuery(viewTarget); // Get the atoms from cellQuery and only keep the ones that // are condition members foreach (JoinTreeSlot slot in cellQuery.GetAllQuerySlots()) { MemberPath member = slot.MemberPath; if (m_domainMap.ContainsKey(member) == false && m_nonConditionDomainMap.ContainsKey(member) == false) { CellConstantSet memberSet = CellConstantDomain.CreateDomainSetFromMemberPath(member, m_workspace); if (member.IsAlwaysDefined(inheritanceGraph) == false) { // nonConditionMember may belong to subclass memberSet.Add(CellConstant.Undefined); } memberSet = CellConstantDomain.NormalizeDomain(memberSet, memberSet); m_nonConditionDomainMap.Add(member, new CellConstantSetInfo(memberSet, slot)); } } } } #endregion #region Fields // Keep track of the actual domain for each member on which we have conditions private Dictionary m_domainMap; // Keep track of the actual domain for each member on which we have no conditions // CellConstantSet in m_nonConditionDomainMap is really CellConstantSetInfo private Dictionary m_nonConditionDomainMap; // Keep track of the different constant values a member could take // (but does not necessarily take), e.g., 3, 4 in this map but its // domain could be just 3 //private Dictionary m_mergedDomainMap; private MetadataWorkspace m_workspace; // members on C-side that are projected, don't have conditions, but the respective S-side members do // we need to threat those just as regular members except in validation, where S-side conditions are // projected to C-side. For that, KB needs to add the respective constraints involving this members // For example: CPerson1.Phone IN {?, NOT(?, NULL)) on C-side. We need to know that // type(CPerson1)=Customer <-> !(CPerson1.Phone IN {?}) for validation of domain constraints private Set m_projectedConditionMembers = new Set (); // struct to keep track of the constant set for a particular slot private class CellConstantSetInfo : CellConstantSet { internal CellConstantSetInfo(Set iconstants, JoinTreeSlot islot) : base(iconstants) { slot = islot; } internal JoinTreeSlot slot; public override string ToString() { return base.ToString(); } } #endregion #region Properties internal bool IsProjectedConditionMember(MemberPath memberPath) { return m_projectedConditionMembers.Contains(memberPath); } #endregion #region Methods // effects: Returns an "open-world" domain, i.e., // one in which not-null constants are used to represent some other value from the domain internal MemberDomainMap GetOpenDomain() { var domainMap = m_domainMap.ToDictionary(p => p.Key, p => new Set (p.Value, CellConstant.EqualityComparer)); AddNegatedConstantsIfNeeded(domainMap); return new MemberDomainMap(domainMap, m_nonConditionDomainMap, m_workspace); } // effects: Creates a deep copy of MemberDomainMap // nonConditionDomainMap is read-only so it is reused without cloning internal MemberDomainMap MakeCopy() { var domainMap = m_domainMap.ToDictionary(p => p.Key, p => new Set (p.Value, CellConstant.EqualityComparer)); return new MemberDomainMap(domainMap, m_nonConditionDomainMap, m_workspace); } // effects: Adds negated constants to the possible set of values if none exists in that set. // Needed so that we can handle cases when discriminator in the store as P, C but could have other values // as well. internal void AddNegatedConstantsToPossibleValues() { AddNegatedConstantsIfNeeded(m_domainMap); } private static void AddNegatedConstantsIfNeeded(Dictionary domainMapForMembers) { // For the S-side, we always says that NOT(...) is // present. For example, if we are told "C", "P", we assume // that NOT(C, P) is possibly present in that column foreach (MemberPath path in domainMapForMembers.Keys) { CellConstantSet possibleValues = domainMapForMembers[path]; if (MetadataHelper.HasDiscreteDomain(path.EdmType) == false && path.IsScalarType() && possibleValues.Any(c => c is NegatedCellConstant) == false) { NegatedCellConstant negatedConstant = new NegatedCellConstant(possibleValues); possibleValues.Add(negatedConstant); } } } // effects: Shrinks the domain of members whose types can be // enumerated, e.g., booleans and enumerated types. For example, // NOT(False, True, Null) for a boolean domain should be removed internal void FixEnumerableDomains(ConfigViewGenerator config) { // Go through the two maps FixEnumerableDomainsInMap(m_domainMap, config, m_workspace); FixEnumerableDomainsInMap(m_nonConditionDomainMap, config, m_workspace); } // effects: Fixes the domains of variables in this as specified in FixEnumerableDomains private static void FixEnumerableDomainsInMap(Dictionary domainMap, ConfigViewGenerator config, MetadataWorkspace workspace) { foreach (MemberPath member in domainMap.Keys) { if (MetadataHelper.HasDiscreteDomain(member.EdmType) == false) { continue; } CellConstantSet domain = CellConstantDomain.CreateDomainSetFromMemberPath(member, workspace); CellConstantSet extra = domainMap[member].Difference(domain); extra.Remove(CellConstant.Undefined); if (extra.Count > 0) { // domainMap has extra members -- we should get rid of them if (config.IsNormalTracing) { Helpers.FormatTraceLine("Changed domain of {0} from {1} - subtract {2}", member, domainMap[member], extra); } domainMap[member].Subtract(extra); } } } // requires: this domainMap has been created for the C-side // effects: Fixes the mergedDomain map in this by merging entries // available in updateDomainMap internal void FixQueryDomainMap(IEnumerable cells, MemberDomainMap updateDomainMap) { foreach (Cell cell in cells) { CellQuery cQuery = cell.CQuery; CellQuery sQuery = cell.SQuery; for (int i = 0; i < cQuery.NumProjectedSlots; i++) { JoinTreeSlot cSlot = cQuery.ProjectedSlotAt(i) as JoinTreeSlot; JoinTreeSlot sSlot = sQuery.ProjectedSlotAt(i) as JoinTreeSlot; if (cSlot == null || sSlot == null) { continue; } // Get the domain for sSlot and merge with cSlot's MemberPath cPath = cSlot.MemberPath; MemberPath sPath = sSlot.MemberPath; CellConstantSet cSet = GetDomainInternal(cPath); CellConstantSet sSet = updateDomainMap.GetDomainInternal(sPath); // skip NULL because if c-side member is nullable, it's already there, and otherwise can't be taken // skip negated because negated values are translated in a special way cSet.Unite(sSet.Where(constant => !constant.IsNull() && !(constant is NegatedCellConstant))); if (updateDomainMap.IsConditionMember(sPath) && !IsConditionMember(cPath)) { // record this member so KB knows we have to generate constraints for it m_projectedConditionMembers.Add(cPath); } } } // Normalize the domains in m_domainMap List | keys = new List (m_domainMap.Keys); foreach (MemberPath path in keys) { CellConstantSet domain = m_domainMap[path]; m_domainMap[path] = CellConstantDomain.NormalizeDomain(domain, domain); } // Normalize the domains in m_nonConditionDomainMap as well keys = new List (m_nonConditionDomainMap.Keys); foreach (MemberPath path in keys) { CellConstantSetInfo domain = (CellConstantSetInfo) m_nonConditionDomainMap[path]; CellConstantSet normalizedDomain = CellConstantDomain.NormalizeDomain(domain, domain); CellConstantSetInfo existingInfo = (CellConstantSetInfo)m_nonConditionDomainMap[path]; m_nonConditionDomainMap[path] = new CellConstantSetInfo(normalizedDomain, existingInfo.slot); } } internal bool IsConditionMember(MemberPath path) { return m_domainMap.ContainsKey(path); } internal IEnumerable ConditionMembers(EntitySetBase extent) { foreach (MemberPath path in m_domainMap.Keys) { if (path.Extent.Equals(extent)) { yield return path; } } } internal IEnumerable NonConditionMembers(EntitySetBase extent) { foreach (MemberPath path in m_nonConditionDomainMap.Keys) { if (path.Extent.Equals(extent)) { yield return path; } } } /// /// Adds AllOtherConstants element to the domain set given by MemberPath /// internal void AddSentinel(MemberPath path) { CellConstantSet set = GetDomainInternal(path); set.Add(CellConstant.AllOtherConstants); } ////// Removes AllOtherConstant element from the domain set given by MemberPath /// internal void RemoveSentinel(MemberPath path) { CellConstantSet set = GetDomainInternal(path); set.Remove(CellConstant.AllOtherConstants); } // requires member exist in this // effects: Returns the possible values/domain for that member internal IEnumerableGetDomain(MemberPath path) { return GetDomainInternal(path); } private CellConstantSet GetDomainInternal(MemberPath path) { CellConstantSet result; bool found = m_domainMap.TryGetValue(path, out result); if (!found) { result = m_nonConditionDomainMap[path]; // It better be in this one! } return result; } // keeps the same set identity for the updated cell constant domain internal void UpdateConditionMemberDomain(MemberPath path, IEnumerable domainValues) { // update domainMap Set oldDomain = m_domainMap[path]; oldDomain.Clear(); oldDomain.Unite(domainValues); } // effects: For member, adds domainValues as the set of values that // member can take. Merges them with any existing values if present private void AddToDomainMap(MemberPath member, IEnumerable domainValues) { CellConstantSet possibleValues; if (false == m_domainMap.TryGetValue(member, out possibleValues)) { possibleValues = new CellConstantSet(CellConstant.EqualityComparer); } possibleValues.Unite(domainValues); // Add the normalized domain to the map so that later uses of the // domain are consistent m_domainMap[member] = CellConstantDomain.NormalizeDomain(possibleValues, possibleValues); } internal override void ToCompactString(StringBuilder builder) { foreach (MemberPath memberPath in m_domainMap.Keys) { builder.Append('('); memberPath.ToCompactString(builder); IEnumerable domain = GetDomain(memberPath); builder.Append(": "); StringUtil.ToCommaSeparatedStringSorted(builder, domain); builder.Append(") "); } } #endregion } } // 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.Collections.Generic; using System.Text; using System.Diagnostics; using System.Data.Mapping.ViewGeneration.Utils; using System.Data.Metadata.Edm; using System.Linq; namespace System.Data.Mapping.ViewGeneration.Structures { using CellConstantSet = Set; // This class keeps track of the domain values of the different members // in a schema. E.g., for a discriminator, it keeps track of "P", // "C"; for type of Person, it keeps track of Person, Customer, etc // It exposes two concepts -- the domain of a member variable and the // different possible values for that member, e.g., the possible values // could be 3, 4, 5 but the domain could be 3, 4 (domain is always a // subset of possibleVales internal class MemberDomainMap : InternalBase { #region Constructor private MemberDomainMap(Dictionary domainMap, Dictionary nonConditionDomainMap, MetadataWorkspace workspace) { m_domainMap = domainMap; m_workspace = workspace; m_nonConditionDomainMap = nonConditionDomainMap; } // effects: Creates a map with all the condition member constants // from extentCells. viewtarget determines whether the view is an // update or query view internal MemberDomainMap(ViewTarget viewTarget, IEnumerable extentCells, MetadataWorkspace workspace, ConfigViewGenerator config, Dictionary | > inheritanceGraph) { m_domainMap = new Dictionary (MemberPath.EqualityComparer); m_workspace = workspace; Dictionary domainMap = null; if (viewTarget == ViewTarget.UpdateView) { domainMap = CellConstantDomain.ComputeConstantDomainSetsForSlotsInUpdateViews(extentCells, workspace); } else { domainMap = CellConstantDomain.ComputeConstantDomainSetsForSlotsInQueryViews(extentCells, workspace); } foreach (Cell cell in extentCells) { CellQuery cellQuery = cell.GetLeftQuery(viewTarget); // Get the atoms from cellQuery and only keep the ones that // are condition members foreach (OneOfConst condition in cellQuery.GetConjunctsFromWhereClause()) { // Note: TypeConditions are created using OneOfTypeConst and // scalars are created using OneOfScalarConst MemberPath memberPath = condition.Slot.MemberPath; if (m_domainMap.ContainsKey(memberPath)) { continue; } Debug.Assert(condition is OneOfScalarConst || condition is OneOfTypeConst, "Unexpected OneOfConst"); // Take the narrowed domain from domainMap, if any CellConstantSet domainValues; if (!domainMap.TryGetValue(memberPath, out domainValues)) { domainValues = CellConstantDomain.CreateDomainSetFromMemberPath(memberPath, m_workspace); } //Don't count conditions that are satisfied through IsNull=false if (!domainValues.Contains(CellConstant.NotNull)) { //multiple values of condition represent disjunction in conditions (not currently supported) // if there is any condition constant that is NotNull if(condition.Values.Values.All(conditionConstant => (conditionConstant.Equals(CellConstant.NotNull)) )) { continue; } //else there is atleast one condition value that is allowed, continue view generation } //IsNull condition on a member that is non nullable is an invalid condition if (domainValues.Count <= 0 || (!domainValues.Contains(CellConstant.Null) && condition.Values.Values.Contains(CellConstant.Null))) { string message = System.Data.Entity.Strings.ViewGen_InvalidCondition_0(memberPath.PathToString(false)); ErrorLog.Record record = new ErrorLog.Record(true, ViewGenErrorCode.InvalidCondition, message, cell, String.Empty); ExceptionHelpers.ThrowMappingException(record, config); } if (memberPath.IsAlwaysDefined(inheritanceGraph) == false) { domainValues.Add(CellConstant.Undefined); } AddToDomainMap(memberPath, domainValues); } } // Fill up the domains for the remaining slots as well m_nonConditionDomainMap = new Dictionary (MemberPath.EqualityComparer); foreach (Cell cell in extentCells) { CellQuery cellQuery = cell.GetLeftQuery(viewTarget); // Get the atoms from cellQuery and only keep the ones that // are condition members foreach (JoinTreeSlot slot in cellQuery.GetAllQuerySlots()) { MemberPath member = slot.MemberPath; if (m_domainMap.ContainsKey(member) == false && m_nonConditionDomainMap.ContainsKey(member) == false) { CellConstantSet memberSet = CellConstantDomain.CreateDomainSetFromMemberPath(member, m_workspace); if (member.IsAlwaysDefined(inheritanceGraph) == false) { // nonConditionMember may belong to subclass memberSet.Add(CellConstant.Undefined); } memberSet = CellConstantDomain.NormalizeDomain(memberSet, memberSet); m_nonConditionDomainMap.Add(member, new CellConstantSetInfo(memberSet, slot)); } } } } #endregion #region Fields // Keep track of the actual domain for each member on which we have conditions private Dictionary m_domainMap; // Keep track of the actual domain for each member on which we have no conditions // CellConstantSet in m_nonConditionDomainMap is really CellConstantSetInfo private Dictionary m_nonConditionDomainMap; // Keep track of the different constant values a member could take // (but does not necessarily take), e.g., 3, 4 in this map but its // domain could be just 3 //private Dictionary m_mergedDomainMap; private MetadataWorkspace m_workspace; // members on C-side that are projected, don't have conditions, but the respective S-side members do // we need to threat those just as regular members except in validation, where S-side conditions are // projected to C-side. For that, KB needs to add the respective constraints involving this members // For example: CPerson1.Phone IN {?, NOT(?, NULL)) on C-side. We need to know that // type(CPerson1)=Customer <-> !(CPerson1.Phone IN {?}) for validation of domain constraints private Set m_projectedConditionMembers = new Set (); // struct to keep track of the constant set for a particular slot private class CellConstantSetInfo : CellConstantSet { internal CellConstantSetInfo(Set iconstants, JoinTreeSlot islot) : base(iconstants) { slot = islot; } internal JoinTreeSlot slot; public override string ToString() { return base.ToString(); } } #endregion #region Properties internal bool IsProjectedConditionMember(MemberPath memberPath) { return m_projectedConditionMembers.Contains(memberPath); } #endregion #region Methods // effects: Returns an "open-world" domain, i.e., // one in which not-null constants are used to represent some other value from the domain internal MemberDomainMap GetOpenDomain() { var domainMap = m_domainMap.ToDictionary(p => p.Key, p => new Set (p.Value, CellConstant.EqualityComparer)); AddNegatedConstantsIfNeeded(domainMap); return new MemberDomainMap(domainMap, m_nonConditionDomainMap, m_workspace); } // effects: Creates a deep copy of MemberDomainMap // nonConditionDomainMap is read-only so it is reused without cloning internal MemberDomainMap MakeCopy() { var domainMap = m_domainMap.ToDictionary(p => p.Key, p => new Set (p.Value, CellConstant.EqualityComparer)); return new MemberDomainMap(domainMap, m_nonConditionDomainMap, m_workspace); } // effects: Adds negated constants to the possible set of values if none exists in that set. // Needed so that we can handle cases when discriminator in the store as P, C but could have other values // as well. internal void AddNegatedConstantsToPossibleValues() { AddNegatedConstantsIfNeeded(m_domainMap); } private static void AddNegatedConstantsIfNeeded(Dictionary domainMapForMembers) { // For the S-side, we always says that NOT(...) is // present. For example, if we are told "C", "P", we assume // that NOT(C, P) is possibly present in that column foreach (MemberPath path in domainMapForMembers.Keys) { CellConstantSet possibleValues = domainMapForMembers[path]; if (MetadataHelper.HasDiscreteDomain(path.EdmType) == false && path.IsScalarType() && possibleValues.Any(c => c is NegatedCellConstant) == false) { NegatedCellConstant negatedConstant = new NegatedCellConstant(possibleValues); possibleValues.Add(negatedConstant); } } } // effects: Shrinks the domain of members whose types can be // enumerated, e.g., booleans and enumerated types. For example, // NOT(False, True, Null) for a boolean domain should be removed internal void FixEnumerableDomains(ConfigViewGenerator config) { // Go through the two maps FixEnumerableDomainsInMap(m_domainMap, config, m_workspace); FixEnumerableDomainsInMap(m_nonConditionDomainMap, config, m_workspace); } // effects: Fixes the domains of variables in this as specified in FixEnumerableDomains private static void FixEnumerableDomainsInMap(Dictionary domainMap, ConfigViewGenerator config, MetadataWorkspace workspace) { foreach (MemberPath member in domainMap.Keys) { if (MetadataHelper.HasDiscreteDomain(member.EdmType) == false) { continue; } CellConstantSet domain = CellConstantDomain.CreateDomainSetFromMemberPath(member, workspace); CellConstantSet extra = domainMap[member].Difference(domain); extra.Remove(CellConstant.Undefined); if (extra.Count > 0) { // domainMap has extra members -- we should get rid of them if (config.IsNormalTracing) { Helpers.FormatTraceLine("Changed domain of {0} from {1} - subtract {2}", member, domainMap[member], extra); } domainMap[member].Subtract(extra); } } } // requires: this domainMap has been created for the C-side // effects: Fixes the mergedDomain map in this by merging entries // available in updateDomainMap internal void FixQueryDomainMap(IEnumerable cells, MemberDomainMap updateDomainMap) { foreach (Cell cell in cells) { CellQuery cQuery = cell.CQuery; CellQuery sQuery = cell.SQuery; for (int i = 0; i < cQuery.NumProjectedSlots; i++) { JoinTreeSlot cSlot = cQuery.ProjectedSlotAt(i) as JoinTreeSlot; JoinTreeSlot sSlot = sQuery.ProjectedSlotAt(i) as JoinTreeSlot; if (cSlot == null || sSlot == null) { continue; } // Get the domain for sSlot and merge with cSlot's MemberPath cPath = cSlot.MemberPath; MemberPath sPath = sSlot.MemberPath; CellConstantSet cSet = GetDomainInternal(cPath); CellConstantSet sSet = updateDomainMap.GetDomainInternal(sPath); // skip NULL because if c-side member is nullable, it's already there, and otherwise can't be taken // skip negated because negated values are translated in a special way cSet.Unite(sSet.Where(constant => !constant.IsNull() && !(constant is NegatedCellConstant))); if (updateDomainMap.IsConditionMember(sPath) && !IsConditionMember(cPath)) { // record this member so KB knows we have to generate constraints for it m_projectedConditionMembers.Add(cPath); } } } // Normalize the domains in m_domainMap List | keys = new List (m_domainMap.Keys); foreach (MemberPath path in keys) { CellConstantSet domain = m_domainMap[path]; m_domainMap[path] = CellConstantDomain.NormalizeDomain(domain, domain); } // Normalize the domains in m_nonConditionDomainMap as well keys = new List (m_nonConditionDomainMap.Keys); foreach (MemberPath path in keys) { CellConstantSetInfo domain = (CellConstantSetInfo) m_nonConditionDomainMap[path]; CellConstantSet normalizedDomain = CellConstantDomain.NormalizeDomain(domain, domain); CellConstantSetInfo existingInfo = (CellConstantSetInfo)m_nonConditionDomainMap[path]; m_nonConditionDomainMap[path] = new CellConstantSetInfo(normalizedDomain, existingInfo.slot); } } internal bool IsConditionMember(MemberPath path) { return m_domainMap.ContainsKey(path); } internal IEnumerable ConditionMembers(EntitySetBase extent) { foreach (MemberPath path in m_domainMap.Keys) { if (path.Extent.Equals(extent)) { yield return path; } } } internal IEnumerable NonConditionMembers(EntitySetBase extent) { foreach (MemberPath path in m_nonConditionDomainMap.Keys) { if (path.Extent.Equals(extent)) { yield return path; } } } /// /// Adds AllOtherConstants element to the domain set given by MemberPath /// internal void AddSentinel(MemberPath path) { CellConstantSet set = GetDomainInternal(path); set.Add(CellConstant.AllOtherConstants); } ////// Removes AllOtherConstant element from the domain set given by MemberPath /// internal void RemoveSentinel(MemberPath path) { CellConstantSet set = GetDomainInternal(path); set.Remove(CellConstant.AllOtherConstants); } // requires member exist in this // effects: Returns the possible values/domain for that member internal IEnumerableGetDomain(MemberPath path) { return GetDomainInternal(path); } private CellConstantSet GetDomainInternal(MemberPath path) { CellConstantSet result; bool found = m_domainMap.TryGetValue(path, out result); if (!found) { result = m_nonConditionDomainMap[path]; // It better be in this one! } return result; } // keeps the same set identity for the updated cell constant domain internal void UpdateConditionMemberDomain(MemberPath path, IEnumerable domainValues) { // update domainMap Set oldDomain = m_domainMap[path]; oldDomain.Clear(); oldDomain.Unite(domainValues); } // effects: For member, adds domainValues as the set of values that // member can take. Merges them with any existing values if present private void AddToDomainMap(MemberPath member, IEnumerable domainValues) { CellConstantSet possibleValues; if (false == m_domainMap.TryGetValue(member, out possibleValues)) { possibleValues = new CellConstantSet(CellConstant.EqualityComparer); } possibleValues.Unite(domainValues); // Add the normalized domain to the map so that later uses of the // domain are consistent m_domainMap[member] = CellConstantDomain.NormalizeDomain(possibleValues, possibleValues); } internal override void ToCompactString(StringBuilder builder) { foreach (MemberPath memberPath in m_domainMap.Keys) { builder.Append('('); memberPath.ToCompactString(builder); IEnumerable domain = GetDomain(memberPath); builder.Append(": "); StringUtil.ToCommaSeparatedStringSorted(builder, domain); builder.Append(") "); } } #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
- ErrorEventArgs.cs
- MenuStrip.cs
- TextRangeSerialization.cs
- CharUnicodeInfo.cs
- GenericXmlSecurityToken.cs
- XmlSchemaAttributeGroup.cs
- ColorIndependentAnimationStorage.cs
- AnnotationService.cs
- ExcludeFromCodeCoverageAttribute.cs
- ReceiveContext.cs
- OdbcParameter.cs
- ToolTip.cs
- wgx_render.cs
- EncoderParameter.cs
- PropertyConverter.cs
- LogLogRecordEnumerator.cs
- CustomPopupPlacement.cs
- FigureHelper.cs
- AgileSafeNativeMemoryHandle.cs
- ColumnPropertiesGroup.cs
- ContainsRowNumberChecker.cs
- TextSpanModifier.cs
- SystemResourceKey.cs
- SoapReflectionImporter.cs
- TextEditor.cs
- DataContractSet.cs
- NamedElement.cs
- InputMethodStateTypeInfo.cs
- SymLanguageVendor.cs
- ScalarType.cs
- SqlNotificationEventArgs.cs
- IndexOutOfRangeException.cs
- StorageAssociationTypeMapping.cs
- SortDescriptionCollection.cs
- DaylightTime.cs
- UserInitiatedRoutedEventPermission.cs
- SpecialFolderEnumConverter.cs
- Oid.cs
- ChangeBlockUndoRecord.cs
- JsonFormatGeneratorStatics.cs
- FilterQuery.cs
- DrawingState.cs
- UInt64.cs
- XmlSchemaSequence.cs
- Wildcard.cs
- ExceptionUtility.cs
- DesignerRegionMouseEventArgs.cs
- SQLSingleStorage.cs
- EditorZoneDesigner.cs
- EventData.cs
- WorkflowDesignerColors.cs
- ListManagerBindingsCollection.cs
- ProtocolImporter.cs
- QilVisitor.cs
- hresults.cs
- ClickablePoint.cs
- SynchronizingStream.cs
- WCFServiceClientProxyGenerator.cs
- SynchronousChannel.cs
- UdpDuplexChannel.cs
- _ServiceNameStore.cs
- DiagnosticTrace.cs
- DataGridViewAutoSizeColumnsModeEventArgs.cs
- ISAPIRuntime.cs
- MulticastNotSupportedException.cs
- SpecularMaterial.cs
- FunctionImportMapping.cs
- WebPartRestoreVerb.cs
- ReflectionUtil.cs
- QuadraticBezierSegment.cs
- ColorPalette.cs
- DurableEnlistmentState.cs
- DetailsViewInsertEventArgs.cs
- DuplicateWaitObjectException.cs
- DataControlFieldCollection.cs
- HttpPostedFile.cs
- Base64Stream.cs
- SerialPinChanges.cs
- OutOfMemoryException.cs
- CFStream.cs
- ColorDialog.cs
- JsonEncodingStreamWrapper.cs
- WindowsScrollBarBits.cs
- ColumnClickEvent.cs
- HandleCollector.cs
- cookie.cs
- RemotingException.cs
- DragDeltaEventArgs.cs
- SpotLight.cs
- TextWriter.cs
- NetworkAddressChange.cs
- HttpWriter.cs
- ScrollItemProviderWrapper.cs
- OdbcEnvironmentHandle.cs
- Serializer.cs
- OneWayChannelFactory.cs
- WebBrowserBase.cs
- AssemblyResourceLoader.cs
- CatalogZoneBase.cs
- ScrollableControl.cs