Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DataEntity / System / Data / Map / ViewGeneration / Structures / MemberDomainMap.cs / 2 / 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 IEnumerable GetDomain(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 IEnumerable GetDomain(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
- DataChangedEventManager.cs
- DateTimeSerializationSection.cs
- TakeQueryOptionExpression.cs
- CurrentChangingEventArgs.cs
- DocumentCollection.cs
- Scene3D.cs
- StructuralType.cs
- DateTimeConstantAttribute.cs
- SinglePhaseEnlistment.cs
- SessionEndedEventArgs.cs
- BeginSelectCardRequest.cs
- SiteMap.cs
- ThreadStateException.cs
- ModuleBuilderData.cs
- Variant.cs
- SemaphoreFullException.cs
- XmlNodeList.cs
- HostProtectionException.cs
- ZipIOZip64EndOfCentralDirectoryBlock.cs
- SystemEvents.cs
- Point3DIndependentAnimationStorage.cs
- NonVisualControlAttribute.cs
- WasAdminWrapper.cs
- OdbcConnectionOpen.cs
- ViewGenResults.cs
- SqlExpressionNullability.cs
- ProcessHostServerConfig.cs
- ValidationManager.cs
- GenericWebPart.cs
- BitmapCodecInfo.cs
- SafeEventLogWriteHandle.cs
- RSAPKCS1SignatureDeformatter.cs
- PropertyGridEditorPart.cs
- SmtpNtlmAuthenticationModule.cs
- TextBoxAutomationPeer.cs
- Baml6Assembly.cs
- MarkupExtensionParser.cs
- ObjectViewQueryResultData.cs
- ProcessThreadCollection.cs
- PathGeometry.cs
- RankException.cs
- OleCmdHelper.cs
- TypedElement.cs
- ProfilePropertyMetadata.cs
- SqlFlattener.cs
- StringDictionaryCodeDomSerializer.cs
- ObjectSelectorEditor.cs
- PartitionResolver.cs
- SyndicationContent.cs
- WebPartCloseVerb.cs
- BrowsableAttribute.cs
- ServicePoint.cs
- EUCJPEncoding.cs
- ConfigurationElementCollection.cs
- LifetimeServices.cs
- WebBrowserPermission.cs
- RandomNumberGenerator.cs
- securitycriticaldata.cs
- Expressions.cs
- RowSpanVector.cs
- Span.cs
- EventMap.cs
- CommonObjectSecurity.cs
- LinqDataSourceStatusEventArgs.cs
- XmlTextEncoder.cs
- ManagementOperationWatcher.cs
- ExceptionAggregator.cs
- MatrixAnimationUsingKeyFrames.cs
- PageAsyncTaskManager.cs
- RecognizedAudio.cs
- AliasGenerator.cs
- TextTreeText.cs
- Span.cs
- WinEventWrap.cs
- XNodeNavigator.cs
- SiteMapNodeCollection.cs
- HyperLinkColumn.cs
- InputLangChangeRequestEvent.cs
- Metafile.cs
- Matrix3D.cs
- DbQueryCommandTree.cs
- ImportCatalogPart.cs
- Symbol.cs
- DefaultValueConverter.cs
- SQLBytesStorage.cs
- SplashScreenNativeMethods.cs
- PersonalizationProviderHelper.cs
- DecimalAnimationUsingKeyFrames.cs
- ProfileServiceManager.cs
- _NestedSingleAsyncResult.cs
- ItemCheckEvent.cs
- TemplatedWizardStep.cs
- FontInfo.cs
- MobileUITypeEditor.cs
- SpecialTypeDataContract.cs
- UnaryNode.cs
- DtcInterfaces.cs
- RequiredAttributeAttribute.cs
- SqlDeflator.cs
- ToolboxItemAttribute.cs