Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Map / ViewGeneration / Structures / MemberDomainMap.cs / 1305376 / 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 Fields // Keep track of the actual domain for each member on which we have conditions // Note: some subtleties: For QueryDomainMap it holds just C-side condition members. For UpdateDominMap // it now holds S-side condition members as well as members with no s-side condition but C-side condition // such that C-side condition restricts the domain of the member(column). private Dictionary m_conditionDomainMap; // 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; // 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 (); private EdmItemCollection m_edmItemCollection; #endregion #region Constructor private MemberDomainMap(Dictionary domainMap, Dictionary nonConditionDomainMap, EdmItemCollection edmItemCollection) { m_conditionDomainMap = domainMap; m_nonConditionDomainMap = nonConditionDomainMap; m_edmItemCollection = edmItemCollection; } // 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, bool isValidationEnabled, IEnumerable extentCells, EdmItemCollection edmItemCollection, ConfigViewGenerator config, Dictionary | > inheritanceGraph) { m_conditionDomainMap = new Dictionary (MemberPath.EqualityComparer); m_edmItemCollection = edmItemCollection; Dictionary domainMap = null; if (viewTarget == ViewTarget.UpdateView) { domainMap = Domain.ComputeConstantDomainSetsForSlotsInUpdateViews(extentCells, m_edmItemCollection); } else { domainMap = Domain.ComputeConstantDomainSetsForSlotsInQueryViews(extentCells, m_edmItemCollection, isValidationEnabled); } 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 (MemberRestriction condition in cellQuery.GetConjunctsFromWhereClause()) { // Note: TypeConditions are created using OneOfTypeConst and // scalars are created using OneOfScalarConst MemberPath memberPath = condition.RestrictedMemberSlot.MemberPath; Debug.Assert(condition is ScalarRestriction || condition is TypeRestriction, "Unexpected restriction"); // Take the narrowed domain from domainMap, if any CellConstantSet domainValues; if (!domainMap.TryGetValue(memberPath, out domainValues)) { domainValues = Domain.DeriveDomainFromMemberPath(memberPath, edmItemCollection, isValidationEnabled); } //Don't count conditions that are satisfied through IsNull=false if (!domainValues.Contains(Constant.Null)) { //multiple values of condition represent disjunction in conditions (not currently supported) // if there is any condition constant that is NotNull if (condition.Domain.Values.All(conditionConstant => (conditionConstant.Equals(Constant.NotNull)))) { continue; } //else there is atleast one condition value that is allowed, continue view generation } //------------------------------------------ //| Nullable | IsNull | Test case | //| T | T | T | //| T | F | T | //| F | T | F | //| F | F | T | //------------------------------------------ //IsNull condition on a member that is non nullable is an invalid condition if (domainValues.Count <= 0 || (!domainValues.Contains(Constant.Null) && condition.Domain.Values.Contains(Constant.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(Constant.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 (MemberProjectedSlot slot in cellQuery.GetAllQuerySlots()) { MemberPath member = slot.MemberPath; if (m_conditionDomainMap.ContainsKey(member) == false && m_nonConditionDomainMap.ContainsKey(member) == false) { CellConstantSet memberSet = Domain.DeriveDomainFromMemberPath(member, m_edmItemCollection, true /* Regardless of validation, leave the domain unbounded because this is not a condition member */); if (member.IsAlwaysDefined(inheritanceGraph) == false) { // nonConditionMember may belong to subclass memberSet.Add(Constant.Undefined); } memberSet = Domain.ExpandNegationsInDomain(memberSet, memberSet); m_nonConditionDomainMap.Add(member, new CellConstantSetInfo(memberSet, slot)); } } } } #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_conditionDomainMap.ToDictionary(p => p.Key, p => new Set (p.Value, Constant.EqualityComparer)); ExpandDomainsIfNeeded(domainMap); return new MemberDomainMap(domainMap, m_nonConditionDomainMap, m_edmItemCollection); } // effects: Creates a deep copy of MemberDomainMap // nonConditionDomainMap is read-only so it is reused without cloning internal MemberDomainMap MakeCopy() { var domainMap = m_conditionDomainMap.ToDictionary(p => p.Key, p => new Set (p.Value, Constant.EqualityComparer)); return new MemberDomainMap(domainMap, m_nonConditionDomainMap, m_edmItemCollection); } // 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 ExpandDomainsToIncludeAllPossibleValues() { ExpandDomainsIfNeeded(m_conditionDomainMap); } private void ExpandDomainsIfNeeded(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 (path.IsScalarType() && possibleValues.Any(c => c is NegatedConstant) == false) { if (MetadataHelper.HasDiscreteDomain(path.EdmType)) { // for a discrete domain, add all values that are not currently represented // in the domain Set completeDomain = Domain.DeriveDomainFromMemberPath(path, m_edmItemCollection, true /* leaveDomainUnbounded */); possibleValues.Unite(completeDomain); } else { // for a non-discrete domain, add NOT("C", "P") NegatedConstant negatedConstant = new NegatedConstant(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 ReduceDomainOfEnumerableToEnumeratedValues(ViewTarget target, ConfigViewGenerator config) { // Go through the two maps ReduceDomainOfEnumerableToEnumeratedValues(target, m_conditionDomainMap, config, m_edmItemCollection); ReduceDomainOfEnumerableToEnumeratedValues(target, m_nonConditionDomainMap, config, m_edmItemCollection); } // effects: Fixes the domains of variables in this as specified in FixEnumerableDomains private static void ReduceDomainOfEnumerableToEnumeratedValues(ViewTarget target, Dictionary domainMap, ConfigViewGenerator config, EdmItemCollection edmItemCollection) { foreach (MemberPath member in domainMap.Keys) { if (MetadataHelper.HasDiscreteDomain(member.EdmType) == false) { continue; } CellConstantSet domain = Domain.DeriveDomainFromMemberPath(member, edmItemCollection, true /* leaveDomainUnbounded */); CellConstantSet extra = domainMap[member].Difference(domain); extra.Remove(Constant.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 static void PropagateUpdateDomainToQueryDomain(IEnumerable cells, MemberDomainMap queryDomainMap, MemberDomainMap updateDomainMap) { foreach (Cell cell in cells) { CellQuery cQuery = cell.CQuery; CellQuery sQuery = cell.SQuery; for (int i = 0; i < cQuery.NumProjectedSlots; i++) { MemberProjectedSlot cSlot = cQuery.ProjectedSlotAt(i) as MemberProjectedSlot; MemberProjectedSlot sSlot = sQuery.ProjectedSlotAt(i) as MemberProjectedSlot; 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 cDomain = queryDomainMap.GetDomainInternal(cPath); CellConstantSet sDomain = 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 cDomain.Unite(sDomain.Where(constant => !constant.IsNull() && !(constant is NegatedConstant))); if (updateDomainMap.IsConditionMember(sPath) && !queryDomainMap.IsConditionMember(cPath)) { // record this member so KB knows we have to generate constraints for it queryDomainMap.m_projectedConditionMembers.Add(cPath); } } } ExpandNegationsInDomainMap(queryDomainMap.m_conditionDomainMap); ExpandNegationsInDomainMap(queryDomainMap.m_nonConditionDomainMap); } private static void ExpandNegationsInDomainMap(Dictionary | > domainMap) { foreach (var path in domainMap.Keys.ToArray()) { domainMap[path] = Domain.ExpandNegationsInDomain(domainMap[path]); } } internal bool IsConditionMember(MemberPath path) { return m_conditionDomainMap.ContainsKey(path); } internal IEnumerable ConditionMembers(EntitySetBase extent) { foreach (MemberPath path in m_conditionDomainMap.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(Constant.AllOtherConstants); } ////// Removes AllOtherConstant element from the domain set given by MemberPath /// internal void RemoveSentinel(MemberPath path) { CellConstantSet set = GetDomainInternal(path); set.Remove(Constant.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_conditionDomainMap.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_conditionDomainMap[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_conditionDomainMap.TryGetValue(member, out possibleValues)) { possibleValues = new CellConstantSet(Constant.EqualityComparer); } possibleValues.Unite(domainValues); // Add the normalized domain to the map so that later uses of the // domain are consistent m_conditionDomainMap[member] = Domain.ExpandNegationsInDomain(possibleValues, possibleValues); } internal override void ToCompactString(StringBuilder builder) { foreach (MemberPath memberPath in m_conditionDomainMap.Keys) { builder.Append('('); memberPath.ToCompactString(builder); IEnumerable domain = GetDomain(memberPath); builder.Append(": "); StringUtil.ToCommaSeparatedStringSorted(builder, domain); builder.Append(") "); } } #endregion // struct to keep track of the constant set for a particular slot private class CellConstantSetInfo : CellConstantSet { internal CellConstantSetInfo(Set iconstants, MemberProjectedSlot islot) : base(iconstants) { slot = islot; } internal MemberProjectedSlot slot; public override string ToString() { return base.ToString(); } } } } // 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 Fields // Keep track of the actual domain for each member on which we have conditions // Note: some subtleties: For QueryDomainMap it holds just C-side condition members. For UpdateDominMap // it now holds S-side condition members as well as members with no s-side condition but C-side condition // such that C-side condition restricts the domain of the member(column). private Dictionary m_conditionDomainMap; // 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; // 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 (); private EdmItemCollection m_edmItemCollection; #endregion #region Constructor private MemberDomainMap(Dictionary domainMap, Dictionary nonConditionDomainMap, EdmItemCollection edmItemCollection) { m_conditionDomainMap = domainMap; m_nonConditionDomainMap = nonConditionDomainMap; m_edmItemCollection = edmItemCollection; } // 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, bool isValidationEnabled, IEnumerable extentCells, EdmItemCollection edmItemCollection, ConfigViewGenerator config, Dictionary | > inheritanceGraph) { m_conditionDomainMap = new Dictionary (MemberPath.EqualityComparer); m_edmItemCollection = edmItemCollection; Dictionary domainMap = null; if (viewTarget == ViewTarget.UpdateView) { domainMap = Domain.ComputeConstantDomainSetsForSlotsInUpdateViews(extentCells, m_edmItemCollection); } else { domainMap = Domain.ComputeConstantDomainSetsForSlotsInQueryViews(extentCells, m_edmItemCollection, isValidationEnabled); } 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 (MemberRestriction condition in cellQuery.GetConjunctsFromWhereClause()) { // Note: TypeConditions are created using OneOfTypeConst and // scalars are created using OneOfScalarConst MemberPath memberPath = condition.RestrictedMemberSlot.MemberPath; Debug.Assert(condition is ScalarRestriction || condition is TypeRestriction, "Unexpected restriction"); // Take the narrowed domain from domainMap, if any CellConstantSet domainValues; if (!domainMap.TryGetValue(memberPath, out domainValues)) { domainValues = Domain.DeriveDomainFromMemberPath(memberPath, edmItemCollection, isValidationEnabled); } //Don't count conditions that are satisfied through IsNull=false if (!domainValues.Contains(Constant.Null)) { //multiple values of condition represent disjunction in conditions (not currently supported) // if there is any condition constant that is NotNull if (condition.Domain.Values.All(conditionConstant => (conditionConstant.Equals(Constant.NotNull)))) { continue; } //else there is atleast one condition value that is allowed, continue view generation } //------------------------------------------ //| Nullable | IsNull | Test case | //| T | T | T | //| T | F | T | //| F | T | F | //| F | F | T | //------------------------------------------ //IsNull condition on a member that is non nullable is an invalid condition if (domainValues.Count <= 0 || (!domainValues.Contains(Constant.Null) && condition.Domain.Values.Contains(Constant.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(Constant.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 (MemberProjectedSlot slot in cellQuery.GetAllQuerySlots()) { MemberPath member = slot.MemberPath; if (m_conditionDomainMap.ContainsKey(member) == false && m_nonConditionDomainMap.ContainsKey(member) == false) { CellConstantSet memberSet = Domain.DeriveDomainFromMemberPath(member, m_edmItemCollection, true /* Regardless of validation, leave the domain unbounded because this is not a condition member */); if (member.IsAlwaysDefined(inheritanceGraph) == false) { // nonConditionMember may belong to subclass memberSet.Add(Constant.Undefined); } memberSet = Domain.ExpandNegationsInDomain(memberSet, memberSet); m_nonConditionDomainMap.Add(member, new CellConstantSetInfo(memberSet, slot)); } } } } #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_conditionDomainMap.ToDictionary(p => p.Key, p => new Set (p.Value, Constant.EqualityComparer)); ExpandDomainsIfNeeded(domainMap); return new MemberDomainMap(domainMap, m_nonConditionDomainMap, m_edmItemCollection); } // effects: Creates a deep copy of MemberDomainMap // nonConditionDomainMap is read-only so it is reused without cloning internal MemberDomainMap MakeCopy() { var domainMap = m_conditionDomainMap.ToDictionary(p => p.Key, p => new Set (p.Value, Constant.EqualityComparer)); return new MemberDomainMap(domainMap, m_nonConditionDomainMap, m_edmItemCollection); } // 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 ExpandDomainsToIncludeAllPossibleValues() { ExpandDomainsIfNeeded(m_conditionDomainMap); } private void ExpandDomainsIfNeeded(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 (path.IsScalarType() && possibleValues.Any(c => c is NegatedConstant) == false) { if (MetadataHelper.HasDiscreteDomain(path.EdmType)) { // for a discrete domain, add all values that are not currently represented // in the domain Set completeDomain = Domain.DeriveDomainFromMemberPath(path, m_edmItemCollection, true /* leaveDomainUnbounded */); possibleValues.Unite(completeDomain); } else { // for a non-discrete domain, add NOT("C", "P") NegatedConstant negatedConstant = new NegatedConstant(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 ReduceDomainOfEnumerableToEnumeratedValues(ViewTarget target, ConfigViewGenerator config) { // Go through the two maps ReduceDomainOfEnumerableToEnumeratedValues(target, m_conditionDomainMap, config, m_edmItemCollection); ReduceDomainOfEnumerableToEnumeratedValues(target, m_nonConditionDomainMap, config, m_edmItemCollection); } // effects: Fixes the domains of variables in this as specified in FixEnumerableDomains private static void ReduceDomainOfEnumerableToEnumeratedValues(ViewTarget target, Dictionary domainMap, ConfigViewGenerator config, EdmItemCollection edmItemCollection) { foreach (MemberPath member in domainMap.Keys) { if (MetadataHelper.HasDiscreteDomain(member.EdmType) == false) { continue; } CellConstantSet domain = Domain.DeriveDomainFromMemberPath(member, edmItemCollection, true /* leaveDomainUnbounded */); CellConstantSet extra = domainMap[member].Difference(domain); extra.Remove(Constant.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 static void PropagateUpdateDomainToQueryDomain(IEnumerable cells, MemberDomainMap queryDomainMap, MemberDomainMap updateDomainMap) { foreach (Cell cell in cells) { CellQuery cQuery = cell.CQuery; CellQuery sQuery = cell.SQuery; for (int i = 0; i < cQuery.NumProjectedSlots; i++) { MemberProjectedSlot cSlot = cQuery.ProjectedSlotAt(i) as MemberProjectedSlot; MemberProjectedSlot sSlot = sQuery.ProjectedSlotAt(i) as MemberProjectedSlot; 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 cDomain = queryDomainMap.GetDomainInternal(cPath); CellConstantSet sDomain = 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 cDomain.Unite(sDomain.Where(constant => !constant.IsNull() && !(constant is NegatedConstant))); if (updateDomainMap.IsConditionMember(sPath) && !queryDomainMap.IsConditionMember(cPath)) { // record this member so KB knows we have to generate constraints for it queryDomainMap.m_projectedConditionMembers.Add(cPath); } } } ExpandNegationsInDomainMap(queryDomainMap.m_conditionDomainMap); ExpandNegationsInDomainMap(queryDomainMap.m_nonConditionDomainMap); } private static void ExpandNegationsInDomainMap(Dictionary | > domainMap) { foreach (var path in domainMap.Keys.ToArray()) { domainMap[path] = Domain.ExpandNegationsInDomain(domainMap[path]); } } internal bool IsConditionMember(MemberPath path) { return m_conditionDomainMap.ContainsKey(path); } internal IEnumerable ConditionMembers(EntitySetBase extent) { foreach (MemberPath path in m_conditionDomainMap.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(Constant.AllOtherConstants); } ////// Removes AllOtherConstant element from the domain set given by MemberPath /// internal void RemoveSentinel(MemberPath path) { CellConstantSet set = GetDomainInternal(path); set.Remove(Constant.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_conditionDomainMap.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_conditionDomainMap[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_conditionDomainMap.TryGetValue(member, out possibleValues)) { possibleValues = new CellConstantSet(Constant.EqualityComparer); } possibleValues.Unite(domainValues); // Add the normalized domain to the map so that later uses of the // domain are consistent m_conditionDomainMap[member] = Domain.ExpandNegationsInDomain(possibleValues, possibleValues); } internal override void ToCompactString(StringBuilder builder) { foreach (MemberPath memberPath in m_conditionDomainMap.Keys) { builder.Append('('); memberPath.ToCompactString(builder); IEnumerable domain = GetDomain(memberPath); builder.Append(": "); StringUtil.ToCommaSeparatedStringSorted(builder, domain); builder.Append(") "); } } #endregion // struct to keep track of the constant set for a particular slot private class CellConstantSetInfo : CellConstantSet { internal CellConstantSetInfo(Set iconstants, MemberProjectedSlot islot) : base(iconstants) { slot = islot; } internal MemberProjectedSlot slot; public override string ToString() { return base.ToString(); } } } } // 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
- SqlClientPermission.cs
- RegexMatchCollection.cs
- AutomationIdentifier.cs
- TransportationConfigurationTypeInstallComponent.cs
- ApplicationFileCodeDomTreeGenerator.cs
- ExtensionFile.cs
- CorrelationRequestContext.cs
- DefaultProxySection.cs
- GroupByQueryOperator.cs
- BasicHttpSecurityMode.cs
- NegatedConstant.cs
- _ScatterGatherBuffers.cs
- ValidatingPropertiesEventArgs.cs
- IPPacketInformation.cs
- Rules.cs
- KnownTypesHelper.cs
- SingleAnimation.cs
- DataMisalignedException.cs
- LZCodec.cs
- WeakEventManager.cs
- TraceListeners.cs
- DataControlFieldCell.cs
- BamlLocalizabilityResolver.cs
- PixelShader.cs
- WebEventCodes.cs
- DoubleAnimationUsingPath.cs
- RuleSetReference.cs
- _ListenerAsyncResult.cs
- ConnectionPoint.cs
- DbException.cs
- DataBindingExpressionBuilder.cs
- HandledEventArgs.cs
- SharedDp.cs
- Win32Exception.cs
- InheritablePropertyChangeInfo.cs
- XsdBuilder.cs
- VariantWrapper.cs
- UpdateManifestForBrowserApplication.cs
- DBConnection.cs
- WindowsServiceCredential.cs
- WorkingDirectoryEditor.cs
- SByteStorage.cs
- SizeConverter.cs
- XmlElementAttributes.cs
- RelationshipEndMember.cs
- DataTableMappingCollection.cs
- XPathItem.cs
- PageStatePersister.cs
- XmlDocument.cs
- UriExt.cs
- HttpListenerResponse.cs
- FormsAuthenticationTicket.cs
- SHA1.cs
- LogLogRecordHeader.cs
- SpeechAudioFormatInfo.cs
- ObjectViewFactory.cs
- MenuScrollingVisibilityConverter.cs
- EntityDataSourceValidationException.cs
- StyleCollectionEditor.cs
- RuntimeConfigLKG.cs
- EditCommandColumn.cs
- SpanIndex.cs
- datacache.cs
- XmlSchemaExporter.cs
- CodeLinePragma.cs
- FieldBuilder.cs
- InvokeMethodActivity.cs
- activationcontext.cs
- X509ChainPolicy.cs
- TabPageDesigner.cs
- SqlMethodCallConverter.cs
- ObjectQueryProvider.cs
- XmlLangPropertyAttribute.cs
- XmlExtensionFunction.cs
- WorkflowWebHostingModule.cs
- DataBinder.cs
- ClientSideProviderDescription.cs
- TextAction.cs
- SocketException.cs
- BitmapCodecInfoInternal.cs
- SHA1CryptoServiceProvider.cs
- InputLanguageCollection.cs
- MoveSizeWinEventHandler.cs
- PageContentAsyncResult.cs
- XmlQueryType.cs
- AttachedPropertyBrowsableAttribute.cs
- TimeoutException.cs
- ListView.cs
- CqlLexerHelpers.cs
- TailPinnedEventArgs.cs
- CollectionEditorDialog.cs
- FieldCollectionEditor.cs
- MeshGeometry3D.cs
- StringUtil.cs
- HMACMD5.cs
- XmlAnyElementAttribute.cs
- CompositeDispatchFormatter.cs
- Crypto.cs
- MultiPageTextView.cs
- ColumnResizeUndoUnit.cs