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 / QueryRewriting / FragmentQueryKB.cs / 1 / FragmentQueryKB.cs
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
// @backupOwner [....]
//---------------------------------------------------------------------
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Text;
using System.Data.Common.Utils;
using System.Data.Common.Utils.Boolean;
using System.Data.Mapping.ViewGeneration.Structures;
using System.Data.Metadata.Edm;
using System.Linq;
namespace System.Data.Mapping.ViewGeneration.QueryRewriting
{
internal class FragmentQueryKB : KnowledgeBase>
{
private BoolExpr> _kbExpression = TrueExpr>.Value;
internal override void AddFact(BoolExpr> fact)
{
base.AddFact(fact);
_kbExpression = new AndExpr>(_kbExpression, fact);
}
internal BoolExpr> KbExpression
{
get { return _kbExpression; }
}
internal void CreateVariableConstraints(EntitySetBase extent, MemberDomainMap domainMap, MetadataWorkspace workspace)
{
CreateVariableConstraintsRecursion(extent.ElementType, new MemberPath(extent, workspace), domainMap, workspace);
}
internal void CreateAssociationConstraints(EntitySetBase extent, MemberDomainMap domainMap, MetadataWorkspace workspace)
{
AssociationSet assocSet = extent as AssociationSet;
if (assocSet != null)
{
BoolExpression assocSetExpr = BoolExpression.CreateLiteral(new RoleBoolean(assocSet), domainMap);
//Set of Keys for this Association Set
//need to key on EdmMember and EdmType because A, B subtype of C, can have the same id (EdmMember) that is defined in C.
HashSet> associationkeys = new HashSet>();
//foreach end, add each Key
foreach(var endMember in assocSet.ElementType.AssociationEndMembers)
{
EntityType type = (EntityType)((RefType)endMember.TypeUsage.EdmType).ElementType;
type.KeyMembers.All(member => associationkeys.Add(new Pair(member, type)) || true /* prevent early termination */);
}
foreach (AssociationSetEnd end in assocSet.AssociationSetEnds)
{
// construct type condition
BoolExpression typeCondition = CreateIsOfTypeCondition(new MemberPath(end.EntitySet, workspace),
end.CorrespondingAssociationEndMember.TypeUsage.EdmType, domainMap, workspace);
BoolExpression inRoleExpression = BoolExpression.CreateLiteral(new RoleBoolean(end), domainMap);
BoolExpression inSetExpression = BoolExpression.CreateAnd(
BoolExpression.CreateLiteral(new RoleBoolean(end.EntitySet), domainMap),
typeCondition);
// InRole -> (InSet AND type(Set)=T)
AddImplication(inRoleExpression.Tree, inSetExpression.Tree);
if (MetadataHelper.IsEveryOtherEndAtLeastOne(assocSet, end.CorrespondingAssociationEndMember))
{
AddImplication(inSetExpression.Tree, inRoleExpression.Tree);
}
// Add equivalence between association set an End/Role if necessary.
// Equivalence is added when a given association end's keys subsumes keys for
// all the other association end.
// For example: We have Entity Sets A[id1], B[id2, id3] and an association A_B between them.
// Ref Constraint A.id1 = B.id2
// In this case, the Association Set has Key
// id1 alone can not identify a unique tuple in the ----Set, but can.
// Therefore we add a constraint: InSet(B) <=> InEnd(A_B.B)
if (MetadataHelper.DoesEndKeySubsumeAssociationSetKey(assocSet,
end.CorrespondingAssociationEndMember,
associationkeys))
{
AddEquivalence(inRoleExpression.Tree, assocSetExpr.Tree);
}
}
// add rules for referential constraints (borrowed from LeftCellWrapper.cs)
AssociationType assocType = assocSet.ElementType;
foreach (ReferentialConstraint constraint in assocType.ReferentialConstraints)
{
AssociationEndMember toEndMember = (AssociationEndMember)constraint.ToRole;
EntitySet toEntitySet = MetadataHelper.GetEntitySetAtEnd(assocSet, toEndMember);
// Check if the keys of the entitySet's are equal to what is specified in the constraint
// How annoying that KeyMembers returns EdmMember and not EdmProperty
IEnumerable toProperties = Helpers.AsSuperTypeList(constraint.ToProperties);
if (Helpers.IsSetEqual(toProperties, toEntitySet.ElementType.KeyMembers, EqualityComparer.Default))
{
// Now check that the FromEnd is 1..1 (only then will all the Addresses be present in the assoc set)
if (constraint.FromRole.RelationshipMultiplicity.Equals(RelationshipMultiplicity.One))
{
// Make sure that the ToEnd is not 0..* because then the schema is broken
Debug.Assert(constraint.ToRole.RelationshipMultiplicity.Equals(RelationshipMultiplicity.Many) == false);
// Equate the ends
BoolExpression inRoleExpression1 = BoolExpression.CreateLiteral(new RoleBoolean(assocSet.AssociationSetEnds[0]), domainMap);
BoolExpression inRoleExpression2 = BoolExpression.CreateLiteral(new RoleBoolean(assocSet.AssociationSetEnds[1]), domainMap);
AddEquivalence(inRoleExpression1.Tree, inRoleExpression2.Tree);
}
}
}
}
}
private void CreateVariableConstraintsRecursion(EdmType edmType, MemberPath currentPath, MemberDomainMap domainMap, MetadataWorkspace workspace)
{
// Add the types can member have, i.e., its type and its subtypes
HashSet possibleTypes = new HashSet();
possibleTypes.UnionWith(MetadataHelper.GetTypeAndSubtypesOf(edmType, workspace, false));
foreach (EdmType possibleType in possibleTypes)
{
// determine type domain
BoolExpression typeCondition = CreateIsOfTypeCondition(currentPath, possibleType, domainMap, workspace);
BoolExpression typeConditionComplement = BoolExpression.CreateNot(typeCondition);
if (false == typeConditionComplement.IsSatisfiable())
{
continue;
}
StructuralType structuralType = (StructuralType)possibleType;
foreach (EdmProperty childProperty in structuralType.GetDeclaredOnlyMembers())
{
MemberPath childPath = new MemberPath(currentPath, childProperty);
bool isScalar = MetadataHelper.IsNonRefSimpleMember(childProperty);
if (domainMap.IsConditionMember(childPath) || domainMap.IsProjectedConditionMember(childPath))
{
BoolExpression nullCondition;
List childDomain = new List(domainMap.GetDomain(childPath));
if (isScalar)
{
nullCondition = BoolExpression.CreateLiteral(new OneOfScalarConst(FragmentQuery.CreateSlot(childPath, workspace),
new CellConstantDomain(ScalarConstant.Undefined, childDomain)), domainMap);
}
else
{
nullCondition = BoolExpression.CreateLiteral(new OneOfTypeConst(FragmentQuery.CreateSlot(childPath, workspace),
new CellConstantDomain(TypeConstant.Undefined, childDomain)), domainMap);
}
// Properties not occuring in type are UNDEFINED
AddEquivalence(typeConditionComplement.Tree, nullCondition.Tree);
}
// recurse into complex types
if (false == isScalar)
{
CreateVariableConstraintsRecursion(childPath.EdmType, childPath, domainMap, workspace);
}
}
}
}
private static BoolExpression CreateIsOfTypeCondition(MemberPath currentPath, EdmType possibleType, MemberDomainMap domainMap, MetadataWorkspace workspace)
{
HashSet derivedTypes = new HashSet();
derivedTypes.UnionWith(MetadataHelper.GetTypeAndSubtypesOf(possibleType, workspace, false));
CellConstantDomain typeDomain = new CellConstantDomain(derivedTypes.Select(derivedType => (CellConstant)new TypeConstant(derivedType)), domainMap.GetDomain(currentPath));
BoolExpression typeCondition = BoolExpression.CreateLiteral(new OneOfTypeConst(FragmentQuery.CreateSlot(currentPath, workspace), typeDomain), domainMap);
return typeCondition;
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
// @backupOwner [....]
//---------------------------------------------------------------------
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Text;
using System.Data.Common.Utils;
using System.Data.Common.Utils.Boolean;
using System.Data.Mapping.ViewGeneration.Structures;
using System.Data.Metadata.Edm;
using System.Linq;
namespace System.Data.Mapping.ViewGeneration.QueryRewriting
{
internal class FragmentQueryKB : KnowledgeBase>
{
private BoolExpr> _kbExpression = TrueExpr>.Value;
internal override void AddFact(BoolExpr> fact)
{
base.AddFact(fact);
_kbExpression = new AndExpr>(_kbExpression, fact);
}
internal BoolExpr> KbExpression
{
get { return _kbExpression; }
}
internal void CreateVariableConstraints(EntitySetBase extent, MemberDomainMap domainMap, MetadataWorkspace workspace)
{
CreateVariableConstraintsRecursion(extent.ElementType, new MemberPath(extent, workspace), domainMap, workspace);
}
internal void CreateAssociationConstraints(EntitySetBase extent, MemberDomainMap domainMap, MetadataWorkspace workspace)
{
AssociationSet assocSet = extent as AssociationSet;
if (assocSet != null)
{
BoolExpression assocSetExpr = BoolExpression.CreateLiteral(new RoleBoolean(assocSet), domainMap);
//Set of Keys for this Association Set
//need to key on EdmMember and EdmType because A, B subtype of C, can have the same id (EdmMember) that is defined in C.
HashSet> associationkeys = new HashSet>();
//foreach end, add each Key
foreach(var endMember in assocSet.ElementType.AssociationEndMembers)
{
EntityType type = (EntityType)((RefType)endMember.TypeUsage.EdmType).ElementType;
type.KeyMembers.All(member => associationkeys.Add(new Pair(member, type)) || true /* prevent early termination */);
}
foreach (AssociationSetEnd end in assocSet.AssociationSetEnds)
{
// construct type condition
BoolExpression typeCondition = CreateIsOfTypeCondition(new MemberPath(end.EntitySet, workspace),
end.CorrespondingAssociationEndMember.TypeUsage.EdmType, domainMap, workspace);
BoolExpression inRoleExpression = BoolExpression.CreateLiteral(new RoleBoolean(end), domainMap);
BoolExpression inSetExpression = BoolExpression.CreateAnd(
BoolExpression.CreateLiteral(new RoleBoolean(end.EntitySet), domainMap),
typeCondition);
// InRole -> (InSet AND type(Set)=T)
AddImplication(inRoleExpression.Tree, inSetExpression.Tree);
if (MetadataHelper.IsEveryOtherEndAtLeastOne(assocSet, end.CorrespondingAssociationEndMember))
{
AddImplication(inSetExpression.Tree, inRoleExpression.Tree);
}
// Add equivalence between association set an End/Role if necessary.
// Equivalence is added when a given association end's keys subsumes keys for
// all the other association end.
// For example: We have Entity Sets A[id1], B[id2, id3] and an association A_B between them.
// Ref Constraint A.id1 = B.id2
// In this case, the Association Set has Key
// id1 alone can not identify a unique tuple in the ----Set, but can.
// Therefore we add a constraint: InSet(B) <=> InEnd(A_B.B)
if (MetadataHelper.DoesEndKeySubsumeAssociationSetKey(assocSet,
end.CorrespondingAssociationEndMember,
associationkeys))
{
AddEquivalence(inRoleExpression.Tree, assocSetExpr.Tree);
}
}
// add rules for referential constraints (borrowed from LeftCellWrapper.cs)
AssociationType assocType = assocSet.ElementType;
foreach (ReferentialConstraint constraint in assocType.ReferentialConstraints)
{
AssociationEndMember toEndMember = (AssociationEndMember)constraint.ToRole;
EntitySet toEntitySet = MetadataHelper.GetEntitySetAtEnd(assocSet, toEndMember);
// Check if the keys of the entitySet's are equal to what is specified in the constraint
// How annoying that KeyMembers returns EdmMember and not EdmProperty
IEnumerable toProperties = Helpers.AsSuperTypeList(constraint.ToProperties);
if (Helpers.IsSetEqual(toProperties, toEntitySet.ElementType.KeyMembers, EqualityComparer.Default))
{
// Now check that the FromEnd is 1..1 (only then will all the Addresses be present in the assoc set)
if (constraint.FromRole.RelationshipMultiplicity.Equals(RelationshipMultiplicity.One))
{
// Make sure that the ToEnd is not 0..* because then the schema is broken
Debug.Assert(constraint.ToRole.RelationshipMultiplicity.Equals(RelationshipMultiplicity.Many) == false);
// Equate the ends
BoolExpression inRoleExpression1 = BoolExpression.CreateLiteral(new RoleBoolean(assocSet.AssociationSetEnds[0]), domainMap);
BoolExpression inRoleExpression2 = BoolExpression.CreateLiteral(new RoleBoolean(assocSet.AssociationSetEnds[1]), domainMap);
AddEquivalence(inRoleExpression1.Tree, inRoleExpression2.Tree);
}
}
}
}
}
private void CreateVariableConstraintsRecursion(EdmType edmType, MemberPath currentPath, MemberDomainMap domainMap, MetadataWorkspace workspace)
{
// Add the types can member have, i.e., its type and its subtypes
HashSet possibleTypes = new HashSet();
possibleTypes.UnionWith(MetadataHelper.GetTypeAndSubtypesOf(edmType, workspace, false));
foreach (EdmType possibleType in possibleTypes)
{
// determine type domain
BoolExpression typeCondition = CreateIsOfTypeCondition(currentPath, possibleType, domainMap, workspace);
BoolExpression typeConditionComplement = BoolExpression.CreateNot(typeCondition);
if (false == typeConditionComplement.IsSatisfiable())
{
continue;
}
StructuralType structuralType = (StructuralType)possibleType;
foreach (EdmProperty childProperty in structuralType.GetDeclaredOnlyMembers())
{
MemberPath childPath = new MemberPath(currentPath, childProperty);
bool isScalar = MetadataHelper.IsNonRefSimpleMember(childProperty);
if (domainMap.IsConditionMember(childPath) || domainMap.IsProjectedConditionMember(childPath))
{
BoolExpression nullCondition;
List childDomain = new List(domainMap.GetDomain(childPath));
if (isScalar)
{
nullCondition = BoolExpression.CreateLiteral(new OneOfScalarConst(FragmentQuery.CreateSlot(childPath, workspace),
new CellConstantDomain(ScalarConstant.Undefined, childDomain)), domainMap);
}
else
{
nullCondition = BoolExpression.CreateLiteral(new OneOfTypeConst(FragmentQuery.CreateSlot(childPath, workspace),
new CellConstantDomain(TypeConstant.Undefined, childDomain)), domainMap);
}
// Properties not occuring in type are UNDEFINED
AddEquivalence(typeConditionComplement.Tree, nullCondition.Tree);
}
// recurse into complex types
if (false == isScalar)
{
CreateVariableConstraintsRecursion(childPath.EdmType, childPath, domainMap, workspace);
}
}
}
}
private static BoolExpression CreateIsOfTypeCondition(MemberPath currentPath, EdmType possibleType, MemberDomainMap domainMap, MetadataWorkspace workspace)
{
HashSet derivedTypes = new HashSet();
derivedTypes.UnionWith(MetadataHelper.GetTypeAndSubtypesOf(possibleType, workspace, false));
CellConstantDomain typeDomain = new CellConstantDomain(derivedTypes.Select(derivedType => (CellConstant)new TypeConstant(derivedType)), domainMap.GetDomain(currentPath));
BoolExpression typeCondition = BoolExpression.CreateLiteral(new OneOfTypeConst(FragmentQuery.CreateSlot(currentPath, workspace), typeDomain), domainMap);
return typeCondition;
}
}
}
// 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
- ZipIOEndOfCentralDirectoryBlock.cs
- SchemaElementLookUpTableEnumerator.cs
- ExceptionHandlerDesigner.cs
- XmlImplementation.cs
- StylusDownEventArgs.cs
- BinaryWriter.cs
- CompositeActivityDesigner.cs
- BCryptSafeHandles.cs
- SkinBuilder.cs
- UdpReplyToBehavior.cs
- login.cs
- RoleBoolean.cs
- RegexInterpreter.cs
- UiaCoreApi.cs
- diagnosticsswitches.cs
- XmlSchemaIdentityConstraint.cs
- LocalFileSettingsProvider.cs
- IntPtr.cs
- ActivationServices.cs
- EntityDataSourceState.cs
- webbrowsersite.cs
- DataMemberAttribute.cs
- UnsafeNativeMethods.cs
- Selection.cs
- NonParentingControl.cs
- ToggleButton.cs
- KeyMatchBuilder.cs
- WindowsRichEditRange.cs
- MobileTemplatedControlDesigner.cs
- DataGridTextBoxColumn.cs
- contentDescriptor.cs
- CodePageUtils.cs
- PrivacyNoticeBindingElement.cs
- HttpResponse.cs
- SecurityDocument.cs
- BindingMAnagerBase.cs
- Variable.cs
- AddInServer.cs
- ToolStripPanelRenderEventArgs.cs
- SpeakInfo.cs
- ScriptMethodAttribute.cs
- SwitchElementsCollection.cs
- ScrollItemPattern.cs
- FunctionImportElement.cs
- XmlMemberMapping.cs
- CallbackValidator.cs
- Screen.cs
- Span.cs
- DiscoveryClient.cs
- WindowVisualStateTracker.cs
- FormViewInsertedEventArgs.cs
- DispatcherHookEventArgs.cs
- SecurityKeyIdentifierClause.cs
- XPathMultyIterator.cs
- DesignTimeVisibleAttribute.cs
- TypeReference.cs
- PageBreakRecord.cs
- DisposableCollectionWrapper.cs
- XmlAttributeOverrides.cs
- PageCanvasSize.cs
- RSAPKCS1SignatureFormatter.cs
- UserNamePasswordServiceCredential.cs
- FlowLayoutSettings.cs
- WSFederationHttpSecurityElement.cs
- BinaryFormatterWriter.cs
- DispatcherHooks.cs
- TypeUtils.cs
- XmlAutoDetectWriter.cs
- Propagator.ExtentPlaceholderCreator.cs
- DataPointer.cs
- UpWmlPageAdapter.cs
- PointConverter.cs
- TiffBitmapDecoder.cs
- LambdaCompiler.Address.cs
- WhitespaceRule.cs
- RelationshipManager.cs
- ExpressionBuilderContext.cs
- GridViewPageEventArgs.cs
- AttributeEmitter.cs
- HttpDictionary.cs
- UserControlAutomationPeer.cs
- SecurityException.cs
- HttpRequest.cs
- CharacterString.cs
- CompilationUnit.cs
- DeadCharTextComposition.cs
- IProducerConsumerCollection.cs
- SchemaConstraints.cs
- XmlIlGenerator.cs
- AssemblyAttributes.cs
- ToolStripSplitButton.cs
- HostedTransportConfigurationBase.cs
- SqlUtil.cs
- XomlCompiler.cs
- ContextInformation.cs
- PhysicalAddress.cs
- NativeWindow.cs
- TextEndOfSegment.cs
- DSASignatureDeformatter.cs
- SecurityDescriptor.cs