Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Map / ViewGeneration / QueryRewriting / FragmentQueryKB.cs / 1305376 / 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, EdmItemCollection edmItemCollection) { CreateVariableConstraintsRecursion(extent.ElementType, new MemberPath(extent), domainMap, edmItemCollection); } internal void CreateAssociationConstraints(EntitySetBase extent, MemberDomainMap domainMap, EdmItemCollection edmItemCollection) { 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 HashSet derivedTypes = new HashSet (); derivedTypes.UnionWith(MetadataHelper.GetTypeAndSubtypesOf(end.CorrespondingAssociationEndMember.TypeUsage.EdmType, edmItemCollection, false)); BoolExpression typeCondition = CreateIsOfTypeCondition(new MemberPath(end.EntitySet), derivedTypes, domainMap); 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 Association 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); } } } } } internal void CreateEquivalenceConstraintForOneToOneForeignKeyAssociation(AssociationSet assocSet, MemberDomainMap domainMap, EdmItemCollection edmItemCollection) { AssociationType assocType = assocSet.ElementType; foreach (ReferentialConstraint constraint in assocType.ReferentialConstraints) { AssociationEndMember toEndMember = (AssociationEndMember)constraint.ToRole; AssociationEndMember fromEndMember = (AssociationEndMember)constraint.FromRole; EntitySet toEntitySet = MetadataHelper.GetEntitySetAtEnd(assocSet, toEndMember); EntitySet fromEntitySet = MetadataHelper.GetEntitySetAtEnd(assocSet, fromEndMember); // Check if the keys of the entitySet's are equal to what is specified in the constraint IEnumerable toProperties = Helpers.AsSuperTypeList (constraint.ToProperties); if (Helpers.IsSetEqual(toProperties, toEntitySet.ElementType.KeyMembers, EqualityComparer .Default)) { //make sure that the method called with a 1:1 association Debug.Assert(constraint.FromRole.RelationshipMultiplicity.Equals(RelationshipMultiplicity.One)); Debug.Assert(constraint.ToRole.RelationshipMultiplicity.Equals(RelationshipMultiplicity.One)); // Create an Equivalence between the two Sets participating in this AssociationSet BoolExpression fromSetExpression = BoolExpression.CreateLiteral(new RoleBoolean(fromEntitySet), domainMap); BoolExpression toSetExpression = BoolExpression.CreateLiteral(new RoleBoolean(toEntitySet), domainMap); AddEquivalence(fromSetExpression.Tree, toSetExpression.Tree); } } } private void CreateVariableConstraintsRecursion(EdmType edmType, MemberPath currentPath, MemberDomainMap domainMap, EdmItemCollection edmItemCollection) { // Add the types can member have, i.e., its type and its subtypes HashSet possibleTypes = new HashSet (); possibleTypes.UnionWith(MetadataHelper.GetTypeAndSubtypesOf(edmType, edmItemCollection, true)); foreach (EdmType possibleType in possibleTypes) { // determine type domain HashSet derivedTypes = new HashSet (); derivedTypes.UnionWith(MetadataHelper.GetTypeAndSubtypesOf(possibleType, edmItemCollection, false)); if (derivedTypes.Count != 0) { BoolExpression typeCondition = CreateIsOfTypeCondition(currentPath, derivedTypes, domainMap); 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 ScalarRestriction(new MemberProjectedSlot(childPath), new Domain(ScalarConstant.Undefined, childDomain)), domainMap); } else { nullCondition = BoolExpression.CreateLiteral(new TypeRestriction(new MemberProjectedSlot(childPath), new Domain(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, edmItemCollection); } } } } } private static BoolExpression CreateIsOfTypeCondition(MemberPath currentPath, IEnumerable derivedTypes, MemberDomainMap domainMap) { Domain typeDomain = new Domain(derivedTypes.Select(derivedType => (Constant)new TypeConstant(derivedType)), domainMap.GetDomain(currentPath)); BoolExpression typeCondition = BoolExpression.CreateLiteral(new TypeRestriction(new MemberProjectedSlot(currentPath), 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, EdmItemCollection edmItemCollection) { CreateVariableConstraintsRecursion(extent.ElementType, new MemberPath(extent), domainMap, edmItemCollection); } internal void CreateAssociationConstraints(EntitySetBase extent, MemberDomainMap domainMap, EdmItemCollection edmItemCollection) { 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 HashSet derivedTypes = new HashSet (); derivedTypes.UnionWith(MetadataHelper.GetTypeAndSubtypesOf(end.CorrespondingAssociationEndMember.TypeUsage.EdmType, edmItemCollection, false)); BoolExpression typeCondition = CreateIsOfTypeCondition(new MemberPath(end.EntitySet), derivedTypes, domainMap); 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 Association 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); } } } } } internal void CreateEquivalenceConstraintForOneToOneForeignKeyAssociation(AssociationSet assocSet, MemberDomainMap domainMap, EdmItemCollection edmItemCollection) { AssociationType assocType = assocSet.ElementType; foreach (ReferentialConstraint constraint in assocType.ReferentialConstraints) { AssociationEndMember toEndMember = (AssociationEndMember)constraint.ToRole; AssociationEndMember fromEndMember = (AssociationEndMember)constraint.FromRole; EntitySet toEntitySet = MetadataHelper.GetEntitySetAtEnd(assocSet, toEndMember); EntitySet fromEntitySet = MetadataHelper.GetEntitySetAtEnd(assocSet, fromEndMember); // Check if the keys of the entitySet's are equal to what is specified in the constraint IEnumerable toProperties = Helpers.AsSuperTypeList (constraint.ToProperties); if (Helpers.IsSetEqual(toProperties, toEntitySet.ElementType.KeyMembers, EqualityComparer .Default)) { //make sure that the method called with a 1:1 association Debug.Assert(constraint.FromRole.RelationshipMultiplicity.Equals(RelationshipMultiplicity.One)); Debug.Assert(constraint.ToRole.RelationshipMultiplicity.Equals(RelationshipMultiplicity.One)); // Create an Equivalence between the two Sets participating in this AssociationSet BoolExpression fromSetExpression = BoolExpression.CreateLiteral(new RoleBoolean(fromEntitySet), domainMap); BoolExpression toSetExpression = BoolExpression.CreateLiteral(new RoleBoolean(toEntitySet), domainMap); AddEquivalence(fromSetExpression.Tree, toSetExpression.Tree); } } } private void CreateVariableConstraintsRecursion(EdmType edmType, MemberPath currentPath, MemberDomainMap domainMap, EdmItemCollection edmItemCollection) { // Add the types can member have, i.e., its type and its subtypes HashSet possibleTypes = new HashSet (); possibleTypes.UnionWith(MetadataHelper.GetTypeAndSubtypesOf(edmType, edmItemCollection, true)); foreach (EdmType possibleType in possibleTypes) { // determine type domain HashSet derivedTypes = new HashSet (); derivedTypes.UnionWith(MetadataHelper.GetTypeAndSubtypesOf(possibleType, edmItemCollection, false)); if (derivedTypes.Count != 0) { BoolExpression typeCondition = CreateIsOfTypeCondition(currentPath, derivedTypes, domainMap); 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 ScalarRestriction(new MemberProjectedSlot(childPath), new Domain(ScalarConstant.Undefined, childDomain)), domainMap); } else { nullCondition = BoolExpression.CreateLiteral(new TypeRestriction(new MemberProjectedSlot(childPath), new Domain(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, edmItemCollection); } } } } } private static BoolExpression CreateIsOfTypeCondition(MemberPath currentPath, IEnumerable derivedTypes, MemberDomainMap domainMap) { Domain typeDomain = new Domain(derivedTypes.Select(derivedType => (Constant)new TypeConstant(derivedType)), domainMap.GetDomain(currentPath)); BoolExpression typeCondition = BoolExpression.CreateLiteral(new TypeRestriction(new MemberProjectedSlot(currentPath), 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
- EventWaitHandle.cs
- MutexSecurity.cs
- TypeInfo.cs
- WindowPattern.cs
- ExecutedRoutedEventArgs.cs
- WmlMobileTextWriter.cs
- ExpressionsCollectionConverter.cs
- ServiceHttpModule.cs
- CallbackValidatorAttribute.cs
- SQLSingleStorage.cs
- DynamicPropertyHolder.cs
- Cursor.cs
- Message.cs
- BindingExpression.cs
- Delegate.cs
- NameSpaceExtractor.cs
- PixelShader.cs
- ExeContext.cs
- MethodExpr.cs
- CurrencyManager.cs
- ProcessHostMapPath.cs
- regiisutil.cs
- X509Certificate2Collection.cs
- XmlNamespaceDeclarationsAttribute.cs
- XmlTypeAttribute.cs
- PolyLineSegmentFigureLogic.cs
- SignedXml.cs
- SamlSubject.cs
- SrgsItemList.cs
- CoTaskMemUnicodeSafeHandle.cs
- RightsManagementEncryptedStream.cs
- EncryptedPackage.cs
- IdentityHolder.cs
- BamlLocalizerErrorNotifyEventArgs.cs
- MethodToken.cs
- ReaderWriterLockSlim.cs
- AstNode.cs
- EntityContainer.cs
- EntityDesignerBuildProvider.cs
- EdmComplexPropertyAttribute.cs
- Processor.cs
- ObservableCollectionDefaultValueFactory.cs
- TreeBuilderBamlTranslator.cs
- ThrowHelper.cs
- HttpWriter.cs
- ExclusiveNamedPipeTransportManager.cs
- ServiceChannelManager.cs
- _TLSstream.cs
- MachineKeySection.cs
- XmlException.cs
- ApplicationDirectoryMembershipCondition.cs
- CodeAttachEventStatement.cs
- OutputScopeManager.cs
- StrokeSerializer.cs
- ElementNotEnabledException.cs
- UrlPath.cs
- ClientOptions.cs
- SafeArrayTypeMismatchException.cs
- HttpPostProtocolImporter.cs
- CompareInfo.cs
- ImmutableCollection.cs
- RegionIterator.cs
- RectAnimationClockResource.cs
- PanelStyle.cs
- RegexBoyerMoore.cs
- NativeRecognizer.cs
- XmlSchemaSimpleContentExtension.cs
- BindingList.cs
- ToolStripItemDesigner.cs
- DataGridViewEditingControlShowingEventArgs.cs
- DataGridViewLinkColumn.cs
- XappLauncher.cs
- XmlCharType.cs
- CriticalHandle.cs
- DrawingCollection.cs
- ForceCopyBuildProvider.cs
- DataGridLengthConverter.cs
- Int64AnimationBase.cs
- QueuedDeliveryRequirementsMode.cs
- Inflater.cs
- Documentation.cs
- LicenseContext.cs
- BooleanStorage.cs
- DtdParser.cs
- SystemResources.cs
- OracleTransaction.cs
- StringCollection.cs
- DocumentPageHost.cs
- NumberFunctions.cs
- InteropTrackingRecord.cs
- StubHelpers.cs
- OneOfConst.cs
- XNodeValidator.cs
- DesignerLoader.cs
- CreateParams.cs
- TreeViewEvent.cs
- SymbolType.cs
- XpsSerializerWriter.cs
- UpDownBase.cs
- Rect3D.cs