FragmentQueryKB.cs source code in C# .NET

Source code for the .NET framework in C#

                        

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

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK