Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataEntity / System / Data / Map / ViewGeneration / CellNormalizer.cs / 2 / CellNormalizer.cs
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
// @backupOwner [....]
//---------------------------------------------------------------------
using System.Data.Common.Utils;
using System.Data.Common.Utils.Boolean;
using System.Data.Mapping.ViewGeneration.Structures;
using System.Collections.Generic;
using System.Text;
using System.Data.Mapping.ViewGeneration.Validation;
using System.Data.Mapping.ViewGeneration.QueryRewriting;
using System.Diagnostics;
using System.Collections.ObjectModel;
using System.Data.Mapping.ViewGeneration.Utils;
using System.Data.Metadata.Edm;
using System.Linq;
namespace System.Data.Mapping.ViewGeneration {
using AttributeSet = Set;
using System.Data.Entity;
// This class is responsible for normalizing the cells for an extent so
// that view generation can occur on the normalized cells.
// Main task: Converts an extent cells to normalized form with
// multiconstants along the needed signatures
// Output: A collection of LeftCellWrappers for the extent. Each wrapper has
// the attriutes, the "right" query, and a set of multiconstants X - these
// multiconstants denote a where clause "variable in X".
internal class CellNormalizer : InternalBase {
#region Constructors
// effects: Given an extent and the cells
// for that extent, creates a CellNormalizer object that is capable
// of returning the normalized cells and the extent signatures when needed
internal CellNormalizer(EntitySetBase extent, IEnumerable extentCells, SchemaContext schemaContext,
CqlIdentifiers identifiers,
ConfigViewGenerator config, MemberDomainMap queryDomainMap,
MemberDomainMap updateDomainMap, StorageEntityContainerMapping entityContainerMapping,
MetadataWorkspace workspace) {
m_extent = extent;
m_schemaContext = schemaContext;
m_config = config;
m_workspace = workspace;
m_entityContainerMapping = entityContainerMapping;
m_identifiers = identifiers;
// Check that the cells that we start out with are ok
ValidateCells(extent, extentCells, schemaContext.ViewTarget);
// create a copy of updateDomainMap so generation of query views later on is not affected
// it is modified in QueryRewriter.AdjustMemberDomainsForUpdateViews
updateDomainMap = updateDomainMap.MakeCopy();
// Create a signature generator that handles all the
// multiconstant work and generating the signatures
MemberDomainMap domainMap = schemaContext.ViewTarget == ViewTarget.QueryView ? queryDomainMap : updateDomainMap;
SignatureGenerator signatureGenerator = new SignatureGenerator(extent, m_workspace);
m_memberMaps = new MemberMaps(schemaContext, signatureGenerator.ProjectedSlotMap,
queryDomainMap, updateDomainMap);
// Create left fragment KB: includes constraints for the extent to be constructed
FragmentQueryKB leftKB = new FragmentQueryKB();
leftKB.CreateVariableConstraints(extent, domainMap, workspace);
m_leftFragmentQP = new FragmentQueryProcessor(leftKB);
m_rewritingCache = new Dictionary>(
FragmentQuery.GetEqualityComparer(m_leftFragmentQP));
// Now using the signatures, create new cells such that
// "extent's" query (C or S) is described in terms of multiconstants
if(!CreateLeftCellWrappers(extentCells, schemaContext.ViewTarget))
{
return;
}
// Create right fragment KB: includes constraints for all extents and association roles of right queries
FragmentQueryKB rightKB = new FragmentQueryKB();
MemberDomainMap rightDomainMap = schemaContext.ViewTarget == ViewTarget.QueryView ? updateDomainMap : queryDomainMap;
foreach (LeftCellWrapper leftCellWrapper in m_cellWrappers)
{
EntitySetBase rightExtent = leftCellWrapper.RightExtent;
rightKB.CreateVariableConstraints(rightExtent, rightDomainMap, workspace);
rightKB.CreateAssociationConstraints(rightExtent, rightDomainMap, workspace);
}
m_rightFragmentQP = new FragmentQueryProcessor(rightKB);
// Check for concurrency control tokens
if (m_schemaContext.ViewTarget == ViewTarget.QueryView)
{
CheckConcurrencyControlTokens();
}
// For backward compatibility -
// order wrappers by increasing domain size, decreasing number of attributes
m_cellWrappers.Sort(LeftCellWrapper.Comparer);
}
#endregion
#region Fields
// Configuration variables
private ConfigViewGenerator m_config;
// Extent for which the cells are being normalized
private EntitySetBase m_extent;
private SchemaContext m_schemaContext;
// Different maps for members
private MemberMaps m_memberMaps;
private MetadataWorkspace m_workspace;
// The normalized cells that are created
private List m_cellWrappers;
// Implicit constraints between members in queries based on schema. E.g., p.Addr IS NOT NULL <=> p IS OF Customer
private FragmentQueryProcessor m_leftFragmentQP;
// In addition to constraints for each right extent contains constraints due to associations
private FragmentQueryProcessor m_rightFragmentQP;
private CqlIdentifiers m_identifiers;
// Maps (left) queries to their rewritings in terms of views
private Dictionary> m_rewritingCache;
private StorageEntityContainerMapping m_entityContainerMapping;
#endregion
#region Properties
internal MemberMaps MemberMaps {
get {
return m_memberMaps;
}
}
// effects: Returns the extent for which the cells have been normalized
internal EntitySetBase Extent {
get { return m_extent; }
}
internal SchemaContext SchemaContext
{
get { return m_schemaContext; }
}
internal ConfigViewGenerator Config
{
get { return m_config; }
}
internal CqlIdentifiers CqlIdentifiers
{
get { return m_identifiers; }
}
internal MetadataWorkspace Workspace
{
get { return m_workspace; }
}
internal FragmentQueryProcessor LeftFragmentQP
{
get { return m_leftFragmentQP; }
}
internal FragmentQueryProcessor RightFragmentQP
{
get { return m_rightFragmentQP; }
}
// effects: Returns all wrappers that were originally relevant for
// this extent
internal List AllWrappersForExtent {
get {
return m_cellWrappers;
}
}
internal StorageEntityContainerMapping EntityContainerMapping
{
get { return m_entityContainerMapping; }
}
#endregion
#region Methods
// effects: Returns the cached rewriting of (left) queries in terms of views, if any
internal bool TryGetCachedRewriting(FragmentQuery query, out Tile rewriting)
{
return m_rewritingCache.TryGetValue(query, out rewriting);
}
// effects: Records the cached rewriting of (left) queries in terms of views
internal void SetCachedRewriting(FragmentQuery query, Tile rewriting)
{
m_rewritingCache[query] = rewriting;
}
// requires: This method be called for query views only
// effects: Checks if the concurrency control tokens are mapped for
// each multiconstant
private void CheckConcurrencyControlTokens() {
// Get the token fields for this extent
EntityTypeBase extentType = m_extent.ElementType;
Set tokenMembers = MetadataHelper.GetConcurrencyMembersForTypeHierarchy(extentType, m_workspace);
Set tokenPaths = new Set(MemberPath.EqualityComparer);
foreach (EdmMember tokenMember in tokenMembers) {
if (tokenMember.DeclaringType.Equals(extentType) == false) {
string message = System.Data.Entity.Strings.ViewGen_Concurrency_Derived_Class_2(tokenMember.Name,
tokenMember.DeclaringType.Name, m_extent);
ErrorLog.Record record = new ErrorLog.Record(true, ViewGenErrorCode.ConcurrencyDerivedClass, message, m_cellWrappers, String.Empty);
ExceptionHelpers.ThrowMappingException(record, m_config);
}
tokenPaths.Add(new MemberPath(m_extent, tokenMember, m_schemaContext.MetadataWorkspace));
}
if (tokenMembers.Count > 0)
{
foreach (LeftCellWrapper wrapper in m_cellWrappers)
{
Set conditionMembers = new Set(
wrapper.OnlyInputCell.CQuery.WhereClause.OneOfConstVariables.Select(oneOf => oneOf.Slot.MemberPath),
MemberPath.EqualityComparer);
conditionMembers.Intersect(tokenPaths);
if (conditionMembers.Count > 0)
{
// There is a condition on concurrency tokens. Throw an exception.
StringBuilder builder = new StringBuilder();
builder.AppendLine(Strings.ViewGen_Concurrency_Invalid_Condition_1(
MemberPath.PropertiesToUserString(conditionMembers, false), m_extent.Name));
ErrorLog.Record record = new ErrorLog.Record(true, ViewGenErrorCode.ConcurrencyTokenHasCondition, builder.ToString(), new LeftCellWrapper[] { wrapper }, String.Empty);
ExceptionHelpers.ThrowMappingException(record, m_config);
}
}
}
}
// effects: Given an extent and its cells, verifies different
// constraints on each cell, e.g., each cell contains mappings for
// the keys (isQueryView indicates if the extent is a C side or S
// side extent). Throws the relevant exception if the validation fails
// If there is a user-visible error (i.e., the user made a mistake,
// throws the real exception for the user)
private static void ValidateCells(EntitySetBase extent, IEnumerable extentCells, ViewTarget viewTarget) {
// Validate the cells for the presence of keys
foreach (Cell cell in extentCells) {
cell.CheckRepInvariant();
CellQuery cellQuery = cell.GetLeftQuery(viewTarget);
// Determine the extent we are recovering
EntitySetBase cellExtent = cellQuery.Extent;
ExceptionHelpers.CheckAndThrowResArgs(extent.Equals(cellExtent), Strings.ViewGen_InputCells_NotIsolated_1,
extent.ElementType.Name, cellExtent.ElementType.Name);
}
}
// effects: Given the cells for the extent (extentCells) along with
// the signatures (multiconstants + needed attributes) for this extent, generates
// the left cell wrappers for it extent (viewTarget indicates whether
// the view is for querying or update purposes
// Modifies m_cellWrappers to contain this list
private bool CreateLeftCellWrappers(IEnumerable extentCells,
ViewTarget viewTarget) {
List extentCellsList = new List(extentCells);
List alignedCells = AlignFields(extentCellsList, m_memberMaps.ProjectedSlotMap, viewTarget);
Debug.Assert(alignedCells.Count == extentCellsList.Count, "Cell counts disagree");
// Go through all the cells and create cell wrappers that can be used for generating the view
m_cellWrappers = new List();
for (int i = 0; i < alignedCells.Count; i++) {
Cell alignedCell = alignedCells[i];
CellQuery left = alignedCell.GetLeftQuery(viewTarget);
CellQuery right = alignedCell.GetRightQuery(viewTarget);
// Obtain the non-null projected slots into attributes
AttributeSet attributes = left.GetNonNullSlots();
BoolExpression fromVariable = BoolExpression.CreateLiteral(new CellIdBoolean(m_identifiers, extentCellsList[i].CellNumber), m_memberMaps.LeftDomainMap);
FragmentQuery fragmentQuery = FragmentQuery.Create(fromVariable, left);
if (viewTarget == ViewTarget.UpdateView)
{
fragmentQuery = m_leftFragmentQP.CreateDerivedViewBySelectingConstantAttributes(fragmentQuery) ?? fragmentQuery;
}
LeftCellWrapper leftWrapper = new LeftCellWrapper(m_schemaContext, attributes, fragmentQuery, right, m_memberMaps,
extentCellsList[i]);
m_cellWrappers.Add(leftWrapper);
}
return true;
}
// effects: Align the fields of each cell in mapping using projectedSlotMap that has a mapping
// for each member of this extent to the slot number of that member in the projected slots
// example:
// input: Proj[A,B,"5"] = Proj[F,"7",G]
// Proj[C,B] = Proj[H,I]
// output: m_projectedSlotMap: A -> 0, B -> 1, C -> 2
// Proj[A,B,null] = Proj[F,"7",null]
// Proj[null,B,C] = Proj[null,I,H]
private static List AlignFields(IEnumerable cells, MemberPathMapBase projectedSlotMap,
ViewTarget viewTarget) {
List outputCells = new List();
// Determine the aligned field for each cell
// The new cells have ProjectedSlotMap.Count number of fields
foreach (Cell cell in cells) {
// If isQueryView is true, we need to consider the C side of
// the cells; otherwise, we look at the S side. Note that we
// CANNOT use cell.LeftQuery since that is determined by
// cell's isQueryView
// The query for which we are constructing the extent
CellQuery mainQuery = cell.GetLeftQuery(viewTarget);
CellQuery otherQuery = cell.GetRightQuery(viewTarget);
CellQuery newMainQuery;
CellQuery newOtherQuery;
// Create both queries where the projected slot map is used
// to determine the order of the fields of the mainquery (of
// course, the otherQuery's fields are aligned automatically)
mainQuery.CreateFieldAlignedCellQueries(otherQuery, projectedSlotMap,
out newMainQuery, out newOtherQuery);
Cell outputCell = viewTarget == ViewTarget.QueryView ?
Cell.CreateCS(newMainQuery, newOtherQuery, cell.CellLabel, cell.CellNumber) :
Cell.CreateCS(newOtherQuery, newMainQuery, cell.CellLabel, cell.CellNumber);
outputCells.Add(outputCell);
}
return outputCells;
}
internal bool IsEmpty(CellTreeNode n)
{
return n.IsEmptyRightFragmentQuery;
}
#endregion
#region String Methods
internal override void ToCompactString(StringBuilder builder) {
LeftCellWrapper.WrappersToStringBuilder(builder, m_cellWrappers, "Left Celll Wrappers");
}
#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.Data.Common.Utils.Boolean;
using System.Data.Mapping.ViewGeneration.Structures;
using System.Collections.Generic;
using System.Text;
using System.Data.Mapping.ViewGeneration.Validation;
using System.Data.Mapping.ViewGeneration.QueryRewriting;
using System.Diagnostics;
using System.Collections.ObjectModel;
using System.Data.Mapping.ViewGeneration.Utils;
using System.Data.Metadata.Edm;
using System.Linq;
namespace System.Data.Mapping.ViewGeneration {
using AttributeSet = Set;
using System.Data.Entity;
// This class is responsible for normalizing the cells for an extent so
// that view generation can occur on the normalized cells.
// Main task: Converts an extent cells to normalized form with
// multiconstants along the needed signatures
// Output: A collection of LeftCellWrappers for the extent. Each wrapper has
// the attriutes, the "right" query, and a set of multiconstants X - these
// multiconstants denote a where clause "variable in X".
internal class CellNormalizer : InternalBase {
#region Constructors
// effects: Given an extent and the cells
// for that extent, creates a CellNormalizer object that is capable
// of returning the normalized cells and the extent signatures when needed
internal CellNormalizer(EntitySetBase extent, IEnumerable extentCells, SchemaContext schemaContext,
CqlIdentifiers identifiers,
ConfigViewGenerator config, MemberDomainMap queryDomainMap,
MemberDomainMap updateDomainMap, StorageEntityContainerMapping entityContainerMapping,
MetadataWorkspace workspace) {
m_extent = extent;
m_schemaContext = schemaContext;
m_config = config;
m_workspace = workspace;
m_entityContainerMapping = entityContainerMapping;
m_identifiers = identifiers;
// Check that the cells that we start out with are ok
ValidateCells(extent, extentCells, schemaContext.ViewTarget);
// create a copy of updateDomainMap so generation of query views later on is not affected
// it is modified in QueryRewriter.AdjustMemberDomainsForUpdateViews
updateDomainMap = updateDomainMap.MakeCopy();
// Create a signature generator that handles all the
// multiconstant work and generating the signatures
MemberDomainMap domainMap = schemaContext.ViewTarget == ViewTarget.QueryView ? queryDomainMap : updateDomainMap;
SignatureGenerator signatureGenerator = new SignatureGenerator(extent, m_workspace);
m_memberMaps = new MemberMaps(schemaContext, signatureGenerator.ProjectedSlotMap,
queryDomainMap, updateDomainMap);
// Create left fragment KB: includes constraints for the extent to be constructed
FragmentQueryKB leftKB = new FragmentQueryKB();
leftKB.CreateVariableConstraints(extent, domainMap, workspace);
m_leftFragmentQP = new FragmentQueryProcessor(leftKB);
m_rewritingCache = new Dictionary>(
FragmentQuery.GetEqualityComparer(m_leftFragmentQP));
// Now using the signatures, create new cells such that
// "extent's" query (C or S) is described in terms of multiconstants
if(!CreateLeftCellWrappers(extentCells, schemaContext.ViewTarget))
{
return;
}
// Create right fragment KB: includes constraints for all extents and association roles of right queries
FragmentQueryKB rightKB = new FragmentQueryKB();
MemberDomainMap rightDomainMap = schemaContext.ViewTarget == ViewTarget.QueryView ? updateDomainMap : queryDomainMap;
foreach (LeftCellWrapper leftCellWrapper in m_cellWrappers)
{
EntitySetBase rightExtent = leftCellWrapper.RightExtent;
rightKB.CreateVariableConstraints(rightExtent, rightDomainMap, workspace);
rightKB.CreateAssociationConstraints(rightExtent, rightDomainMap, workspace);
}
m_rightFragmentQP = new FragmentQueryProcessor(rightKB);
// Check for concurrency control tokens
if (m_schemaContext.ViewTarget == ViewTarget.QueryView)
{
CheckConcurrencyControlTokens();
}
// For backward compatibility -
// order wrappers by increasing domain size, decreasing number of attributes
m_cellWrappers.Sort(LeftCellWrapper.Comparer);
}
#endregion
#region Fields
// Configuration variables
private ConfigViewGenerator m_config;
// Extent for which the cells are being normalized
private EntitySetBase m_extent;
private SchemaContext m_schemaContext;
// Different maps for members
private MemberMaps m_memberMaps;
private MetadataWorkspace m_workspace;
// The normalized cells that are created
private List m_cellWrappers;
// Implicit constraints between members in queries based on schema. E.g., p.Addr IS NOT NULL <=> p IS OF Customer
private FragmentQueryProcessor m_leftFragmentQP;
// In addition to constraints for each right extent contains constraints due to associations
private FragmentQueryProcessor m_rightFragmentQP;
private CqlIdentifiers m_identifiers;
// Maps (left) queries to their rewritings in terms of views
private Dictionary> m_rewritingCache;
private StorageEntityContainerMapping m_entityContainerMapping;
#endregion
#region Properties
internal MemberMaps MemberMaps {
get {
return m_memberMaps;
}
}
// effects: Returns the extent for which the cells have been normalized
internal EntitySetBase Extent {
get { return m_extent; }
}
internal SchemaContext SchemaContext
{
get { return m_schemaContext; }
}
internal ConfigViewGenerator Config
{
get { return m_config; }
}
internal CqlIdentifiers CqlIdentifiers
{
get { return m_identifiers; }
}
internal MetadataWorkspace Workspace
{
get { return m_workspace; }
}
internal FragmentQueryProcessor LeftFragmentQP
{
get { return m_leftFragmentQP; }
}
internal FragmentQueryProcessor RightFragmentQP
{
get { return m_rightFragmentQP; }
}
// effects: Returns all wrappers that were originally relevant for
// this extent
internal List AllWrappersForExtent {
get {
return m_cellWrappers;
}
}
internal StorageEntityContainerMapping EntityContainerMapping
{
get { return m_entityContainerMapping; }
}
#endregion
#region Methods
// effects: Returns the cached rewriting of (left) queries in terms of views, if any
internal bool TryGetCachedRewriting(FragmentQuery query, out Tile rewriting)
{
return m_rewritingCache.TryGetValue(query, out rewriting);
}
// effects: Records the cached rewriting of (left) queries in terms of views
internal void SetCachedRewriting(FragmentQuery query, Tile rewriting)
{
m_rewritingCache[query] = rewriting;
}
// requires: This method be called for query views only
// effects: Checks if the concurrency control tokens are mapped for
// each multiconstant
private void CheckConcurrencyControlTokens() {
// Get the token fields for this extent
EntityTypeBase extentType = m_extent.ElementType;
Set tokenMembers = MetadataHelper.GetConcurrencyMembersForTypeHierarchy(extentType, m_workspace);
Set tokenPaths = new Set(MemberPath.EqualityComparer);
foreach (EdmMember tokenMember in tokenMembers) {
if (tokenMember.DeclaringType.Equals(extentType) == false) {
string message = System.Data.Entity.Strings.ViewGen_Concurrency_Derived_Class_2(tokenMember.Name,
tokenMember.DeclaringType.Name, m_extent);
ErrorLog.Record record = new ErrorLog.Record(true, ViewGenErrorCode.ConcurrencyDerivedClass, message, m_cellWrappers, String.Empty);
ExceptionHelpers.ThrowMappingException(record, m_config);
}
tokenPaths.Add(new MemberPath(m_extent, tokenMember, m_schemaContext.MetadataWorkspace));
}
if (tokenMembers.Count > 0)
{
foreach (LeftCellWrapper wrapper in m_cellWrappers)
{
Set conditionMembers = new Set(
wrapper.OnlyInputCell.CQuery.WhereClause.OneOfConstVariables.Select(oneOf => oneOf.Slot.MemberPath),
MemberPath.EqualityComparer);
conditionMembers.Intersect(tokenPaths);
if (conditionMembers.Count > 0)
{
// There is a condition on concurrency tokens. Throw an exception.
StringBuilder builder = new StringBuilder();
builder.AppendLine(Strings.ViewGen_Concurrency_Invalid_Condition_1(
MemberPath.PropertiesToUserString(conditionMembers, false), m_extent.Name));
ErrorLog.Record record = new ErrorLog.Record(true, ViewGenErrorCode.ConcurrencyTokenHasCondition, builder.ToString(), new LeftCellWrapper[] { wrapper }, String.Empty);
ExceptionHelpers.ThrowMappingException(record, m_config);
}
}
}
}
// effects: Given an extent and its cells, verifies different
// constraints on each cell, e.g., each cell contains mappings for
// the keys (isQueryView indicates if the extent is a C side or S
// side extent). Throws the relevant exception if the validation fails
// If there is a user-visible error (i.e., the user made a mistake,
// throws the real exception for the user)
private static void ValidateCells(EntitySetBase extent, IEnumerable extentCells, ViewTarget viewTarget) {
// Validate the cells for the presence of keys
foreach (Cell cell in extentCells) {
cell.CheckRepInvariant();
CellQuery cellQuery = cell.GetLeftQuery(viewTarget);
// Determine the extent we are recovering
EntitySetBase cellExtent = cellQuery.Extent;
ExceptionHelpers.CheckAndThrowResArgs(extent.Equals(cellExtent), Strings.ViewGen_InputCells_NotIsolated_1,
extent.ElementType.Name, cellExtent.ElementType.Name);
}
}
// effects: Given the cells for the extent (extentCells) along with
// the signatures (multiconstants + needed attributes) for this extent, generates
// the left cell wrappers for it extent (viewTarget indicates whether
// the view is for querying or update purposes
// Modifies m_cellWrappers to contain this list
private bool CreateLeftCellWrappers(IEnumerable extentCells,
ViewTarget viewTarget) {
List extentCellsList = new List(extentCells);
List alignedCells = AlignFields(extentCellsList, m_memberMaps.ProjectedSlotMap, viewTarget);
Debug.Assert(alignedCells.Count == extentCellsList.Count, "Cell counts disagree");
// Go through all the cells and create cell wrappers that can be used for generating the view
m_cellWrappers = new List();
for (int i = 0; i < alignedCells.Count; i++) {
Cell alignedCell = alignedCells[i];
CellQuery left = alignedCell.GetLeftQuery(viewTarget);
CellQuery right = alignedCell.GetRightQuery(viewTarget);
// Obtain the non-null projected slots into attributes
AttributeSet attributes = left.GetNonNullSlots();
BoolExpression fromVariable = BoolExpression.CreateLiteral(new CellIdBoolean(m_identifiers, extentCellsList[i].CellNumber), m_memberMaps.LeftDomainMap);
FragmentQuery fragmentQuery = FragmentQuery.Create(fromVariable, left);
if (viewTarget == ViewTarget.UpdateView)
{
fragmentQuery = m_leftFragmentQP.CreateDerivedViewBySelectingConstantAttributes(fragmentQuery) ?? fragmentQuery;
}
LeftCellWrapper leftWrapper = new LeftCellWrapper(m_schemaContext, attributes, fragmentQuery, right, m_memberMaps,
extentCellsList[i]);
m_cellWrappers.Add(leftWrapper);
}
return true;
}
// effects: Align the fields of each cell in mapping using projectedSlotMap that has a mapping
// for each member of this extent to the slot number of that member in the projected slots
// example:
// input: Proj[A,B,"5"] = Proj[F,"7",G]
// Proj[C,B] = Proj[H,I]
// output: m_projectedSlotMap: A -> 0, B -> 1, C -> 2
// Proj[A,B,null] = Proj[F,"7",null]
// Proj[null,B,C] = Proj[null,I,H]
private static List AlignFields(IEnumerable cells, MemberPathMapBase projectedSlotMap,
ViewTarget viewTarget) {
List outputCells = new List| ();
// Determine the aligned field for each cell
// The new cells have ProjectedSlotMap.Count number of fields
foreach (Cell cell in cells) {
// If isQueryView is true, we need to consider the C side of
// the cells; otherwise, we look at the S side. Note that we
// CANNOT use cell.LeftQuery since that is determined by
// cell's isQueryView
// The query for which we are constructing the extent
CellQuery mainQuery = cell.GetLeftQuery(viewTarget);
CellQuery otherQuery = cell.GetRightQuery(viewTarget);
CellQuery newMainQuery;
CellQuery newOtherQuery;
// Create both queries where the projected slot map is used
// to determine the order of the fields of the mainquery (of
// course, the otherQuery's fields are aligned automatically)
mainQuery.CreateFieldAlignedCellQueries(otherQuery, projectedSlotMap,
out newMainQuery, out newOtherQuery);
Cell outputCell = viewTarget == ViewTarget.QueryView ?
Cell.CreateCS(newMainQuery, newOtherQuery, cell.CellLabel, cell.CellNumber) :
Cell.CreateCS(newOtherQuery, newMainQuery, cell.CellLabel, cell.CellNumber);
outputCells.Add(outputCell);
}
return outputCells;
}
internal bool IsEmpty(CellTreeNode n)
{
return n.IsEmptyRightFragmentQuery;
}
#endregion
#region String Methods
internal override void ToCompactString(StringBuilder builder) {
LeftCellWrapper.WrappersToStringBuilder(builder, m_cellWrappers, "Left Celll Wrappers");
}
#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
- XmlElementList.cs
- StubHelpers.cs
- DomainUpDown.cs
- IfJoinedCondition.cs
- WinOEToolBoxItem.cs
- DocumentPageViewAutomationPeer.cs
- Image.cs
- RankException.cs
- SystemBrushes.cs
- ResourceProperty.cs
- InertiaExpansionBehavior.cs
- TableRowCollection.cs
- BooleanFunctions.cs
- VerificationException.cs
- FontUnit.cs
- TdsValueSetter.cs
- HostingEnvironmentSection.cs
- XamlInterfaces.cs
- DesignerSerializationVisibilityAttribute.cs
- BookmarkEventArgs.cs
- InsufficientMemoryException.cs
- BaseTemplateBuildProvider.cs
- WebPartMinimizeVerb.cs
- BaseParser.cs
- ImmComposition.cs
- Stack.cs
- Double.cs
- SendMailErrorEventArgs.cs
- WebPartRestoreVerb.cs
- LostFocusEventManager.cs
- ColorContextHelper.cs
- VideoDrawing.cs
- ArgumentOutOfRangeException.cs
- Geometry3D.cs
- PointAnimationBase.cs
- ValidationRuleCollection.cs
- Error.cs
- DbMetaDataColumnNames.cs
- StructuralType.cs
- XpsFontSerializationService.cs
- SupportsEventValidationAttribute.cs
- DBAsyncResult.cs
- TextFormatterContext.cs
- DataGridViewCellPaintingEventArgs.cs
- DataGridColumnCollectionEditor.cs
- ReadOnlyNameValueCollection.cs
- PermissionSetEnumerator.cs
- SemanticResolver.cs
- SmiSettersStream.cs
- EntitySetBase.cs
- ClientBuildManagerCallback.cs
- BitmapEffectrendercontext.cs
- Normalization.cs
- RuleSettingsCollection.cs
- TrustLevel.cs
- ProfileSettings.cs
- FormViewUpdateEventArgs.cs
- XmlUrlResolver.cs
- OleDbFactory.cs
- ObjectSet.cs
- WriteTimeStream.cs
- ValidationHelper.cs
- ArrayElementGridEntry.cs
- XamlDebuggerXmlReader.cs
- DataDesignUtil.cs
- DbDeleteCommandTree.cs
- RouteItem.cs
- XslException.cs
- ServicePointManagerElement.cs
- StructuredProperty.cs
- ToolboxItemAttribute.cs
- DynamicPhysicalDiscoSearcher.cs
- HtmlWindowCollection.cs
- DataControlFieldCollection.cs
- XmlDataContract.cs
- KeyValueSerializer.cs
- WCFBuildProvider.cs
- SrgsSubset.cs
- ADConnectionHelper.cs
- NumericUpDownAcceleration.cs
- CqlErrorHelper.cs
- ColorDialog.cs
- SerializationObjectManager.cs
- Renderer.cs
- DataObjectPastingEventArgs.cs
- EmptyCollection.cs
- DrawingImage.cs
- AutomationIdentifierGuids.cs
- FuncTypeConverter.cs
- ObjectStateEntryBaseUpdatableDataRecord.cs
- BindableTemplateBuilder.cs
- sortedlist.cs
- NumericUpDownAcceleration.cs
- clipboard.cs
- GridViewSortEventArgs.cs
- ReflectionPermission.cs
- FactoryMaker.cs
- UrlMappingsModule.cs
- SqlGenericUtil.cs
- AnnotationHelper.cs