Exemplo n.º 1
0
        /// <summary>
        /// Queries for a specified resource.
        /// </summary>
        /// <param name="parameters">The parameters.</param>
        /// <returns>Returns the FHIR query result containing the results of the query.</returns>
        /// <exception cref="System.ArgumentNullException">parameters</exception>
        public virtual FhirQueryResult Query(System.Collections.Specialized.NameValueCollection parameters)
        {
            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }

            Core.Model.Query.NameValueCollection imsiQuery = null;
            FhirQuery query = QueryRewriter.RewriteFhirQuery <TFhirResource, TModel>(parameters, out imsiQuery);

            // Do the query
            int totalResults            = 0;
            List <IResultDetail> issues = new List <IResultDetail>();
            var predicate           = QueryExpressionParser.BuildLinqExpression <TModel>(imsiQuery);
            var imsiResults         = this.Query(predicate, issues, query.QueryId, query.Start, query.Quantity, out totalResults);
            var webOperationContext = WebOperationContext.Current;

            // Return FHIR query result
            return(new FhirQueryResult()
            {
                Details = issues,
                Outcome = ResultCode.Accepted,
                Results = imsiResults.AsParallel().Select(o => this.MapToFhir(o, webOperationContext)).OfType <DomainResourceBase>().ToList(),
                Query = query,
                TotalResults = totalResults
            });
        }
Exemplo n.º 2
0
        private QueryRewriter GenerateDirectionalViewsForExtent(
            ViewTarget viewTarget,
            EntitySetBase extent,
            CqlIdentifiers identifiers,
            KeyToListMap <EntitySetBase, GeneratedView> views)
        {
            ViewgenContext viewgenContext = this.CreateViewgenContext(extent, viewTarget, identifiers);
            QueryRewriter  queryRewriter  = (QueryRewriter)null;

            if (this.m_config.GenerateViewsForEachType)
            {
                foreach (EdmType generatedType in MetadataHelper.GetTypeAndSubtypesOf((EdmType)extent.ElementType, (ItemCollection)this.m_entityContainerMapping.StorageMappingItemCollection.EdmItemCollection, false))
                {
                    if (this.m_config.IsViewTracing && !generatedType.Equals((object)extent.ElementType))
                    {
                        Helpers.FormatTraceLine("CQL View for {0} and type {1}", (object)extent.Name, (object)generatedType.Name);
                    }
                    queryRewriter = this.GenerateViewsForExtentAndType(generatedType, viewgenContext, identifiers, views, ViewGenMode.OfTypeViews);
                }
            }
            else
            {
                queryRewriter = this.GenerateViewsForExtentAndType((EdmType)extent.ElementType, viewgenContext, identifiers, views, ViewGenMode.OfTypeViews);
            }
            if (viewTarget == ViewTarget.QueryView)
            {
                this.m_config.SetTimeForFinishedActivity(PerfType.QueryViews);
            }
            else
            {
                this.m_config.SetTimeForFinishedActivity(PerfType.UpdateViews);
            }
            this.m_queryRewriterCache[extent] = queryRewriter;
            return(queryRewriter);
        }
Exemplo n.º 3
0
        public void TestGetSearchParams()
        {
            var actual = QueryRewriter.GetSearchParams <Patient, Core.Model.Roles.Patient>();

            // TODO: add more assertions
            Assert.IsTrue(actual.Any());
        }
        // requires: constraint.ChildColumns form a key in
        // constraint.ChildTable (actually they should subsume the primary key)
        private void GuaranteeForeignKeyConstraintInCSpace(QueryRewriter childRewriter, QueryRewriter parentRewriter,
                                                           ErrorLog errorLog, ConfigViewGenerator config)
        {
            ViewgenContext childContext  = childRewriter.ViewgenContext;
            ViewgenContext parentContext = parentRewriter.ViewgenContext;
            CellTreeNode   cNode         = childRewriter.BasicView;
            CellTreeNode   pNode         = parentRewriter.BasicView;

            FragmentQueryProcessor qp = FragmentQueryProcessor.Merge(childContext.RightFragmentQP, parentContext.RightFragmentQP);
            bool cImpliesP            = qp.IsContainedIn(cNode.RightFragmentQuery, pNode.RightFragmentQuery);

            if (false == cImpliesP)
            {
                // Foreign key constraint not being ensured in C-space
                string childExtents  = LeftCellWrapper.GetExtentListAsUserString(cNode.GetLeaves());
                string parentExtents = LeftCellWrapper.GetExtentListAsUserString(pNode.GetLeaves());
                string message       = System.Data.Entity.Strings.ViewGen_Foreign_Key_Not_Guaranteed_InCSpace(
                    ToUserString());
                // Add all wrappers into allWrappers
                Set <LeftCellWrapper> allWrappers = new Set <LeftCellWrapper>(pNode.GetLeaves());
                allWrappers.AddRange(cNode.GetLeaves());
                ErrorLog.Record record = new ErrorLog.Record(true, ViewGenErrorCode.ForeignKeyNotGuaranteedInCSpace, message, allWrappers, String.Empty);
                errorLog.AddEntry(record);
            }
        }
Exemplo n.º 5
0
        // requires: constraint.ChildColumns form a key in
        // constraint.ChildTable (actually they should subsume the primary key)
        private void GuaranteeForeignKeyConstraintInCSpace(
            QueryRewriter childRewriter, QueryRewriter parentRewriter,
            ErrorLog errorLog)
        {
            var childContext  = childRewriter.ViewgenContext;
            var parentContext = parentRewriter.ViewgenContext;
            var cNode         = childRewriter.BasicView;
            var pNode         = parentRewriter.BasicView;

            var qp        = FragmentQueryProcessor.Merge(childContext.RightFragmentQP, parentContext.RightFragmentQP);
            var cImpliesP = qp.IsContainedIn(cNode.RightFragmentQuery, pNode.RightFragmentQuery);

            if (false == cImpliesP)
            {
                // Foreign key constraint not being ensured in C-space
                var childExtents  = LeftCellWrapper.GetExtentListAsUserString(cNode.GetLeaves());
                var parentExtents = LeftCellWrapper.GetExtentListAsUserString(pNode.GetLeaves());
                var message       = Strings.ViewGen_Foreign_Key_Not_Guaranteed_InCSpace(
                    ToUserString());
                // Add all wrappers into allWrappers
                var allWrappers = new Set <LeftCellWrapper>(pNode.GetLeaves());
                allWrappers.AddRange(cNode.GetLeaves());
                var record = new ErrorLog.Record(ViewGenErrorCode.ForeignKeyNotGuaranteedInCSpace, message, allWrappers, String.Empty);
                errorLog.AddEntry(record);
            }
        }
Exemplo n.º 6
0
        public override void Given()
        {
            base.Given();

            WorkItemStore = TimedAction(() => IntegrationSettings.CreateRestStore(), "REST", "WIS Create");

            ConfigureOptions();

            var pr         = new PropertyReflector();
            var pi         = new PropertyInspector(pr);
            var attMapper  = new AttributeMapperStrategy(pi);
            var mapper     = new WorkItemMapper(attMapper);
            var translator = new WiqlTranslator();
            var pe         = new PartialEvaluator();
            var qr         = new QueryRewriter();
            var wqb        = new WiqlQueryBuilder(translator, pe, qr);
            var qp         = new MapperTeamFoundationServerWorkItemQueryProvider(
                WorkItemStore,
                wqb,
                mapper);

            Query = new Query <Bug>(qp, wqb);

            _ids = new[]
            {
                8663955
            };
        }
        private ErrorLog GenerateQueryViewForExtentAndType(StorageEntityContainerMapping entityContainerMapping, CqlIdentifiers identifiers, ViewSet views, EntitySetBase entity, EntityTypeBase type, ViewGenMode mode)
        {
            Debug.Assert(mode != ViewGenMode.GenerateAllViews);

            // Keep track of the mapping exceptions that we have generated
            ErrorLog errorLog = new ErrorLog();

            if (m_config.IsViewTracing)
            {
                Helpers.StringTraceLine(String.Empty);
                Helpers.StringTraceLine(String.Empty);
                Helpers.FormatTraceLine("================= Generating {0} Query View for: {1} ===========================",
                                        (mode == ViewGenMode.OfTypeViews) ? "OfType" : "OfTypeOnly",
                                        entity.Name);
                Helpers.StringTraceLine(String.Empty);
                Helpers.StringTraceLine(String.Empty);
            }

            try
            {
                // (1) view generation (checks that extents are fully mapped)
                ViewgenContext context       = CreateViewgenContext(entity, ViewTarget.QueryView, identifiers);
                QueryRewriter  queryRewriter = GenerateViewsForExtentAndType(type, context, identifiers, views, mode);
            }
            catch (InternalMappingException exception)
            {
                // All exceptions have mapping errors in them
                Debug.Assert(exception.ErrorLog.Count > 0, "Incorrectly created mapping exception");
                errorLog.Merge(exception.ErrorLog);
            }

            return(errorLog);
        }
Exemplo n.º 8
0
        private QueryRewriter GenerateViewsForExtentAndType(
            EdmType generatedType, ViewgenContext context, CqlIdentifiers identifiers, ViewSet views, ViewGenMode mode)
        {
            Debug.Assert(mode != ViewGenMode.GenerateAllViews, "By definition this method can not handle generating views for all extents");

            var queryRewriter = new QueryRewriter(generatedType, context, mode);

            queryRewriter.GenerateViewComponents();

            // Get the basic view
            var basicView = queryRewriter.BasicView;

            if (m_config.IsNormalTracing)
            {
                Helpers.StringTrace("Basic View: ");
                Helpers.StringTraceLine(basicView.ToString());
            }

            var simplifiedView = GenerateSimplifiedView(basicView, queryRewriter.UsedCells);

            if (m_config.IsNormalTracing)
            {
                Helpers.StringTraceLine(String.Empty);
                Helpers.StringTrace("Simplified View: ");
                Helpers.StringTraceLine(simplifiedView.ToString());
            }

            var cqlGen = new CqlGenerator(
                simplifiedView,
                queryRewriter.CaseStatements,
                identifiers,
                context.MemberMaps.ProjectedSlotMap,
                queryRewriter.UsedCells.Count,
                queryRewriter.TopLevelWhereClause,
                m_entityContainerMapping.StorageMappingItemCollection);

            string             eSQLView;
            DbQueryCommandTree commandTree;

            if (m_config.GenerateEsql)
            {
                eSQLView    = cqlGen.GenerateEsql();
                commandTree = null;
            }
            else
            {
                eSQLView    = null;
                commandTree = cqlGen.GenerateCqt();
            }

            var generatedView = GeneratedView.CreateGeneratedView(
                context.Extent, generatedType, commandTree, eSQLView, m_entityContainerMapping.StorageMappingItemCollection, m_config);

            views.Add(context.Extent, generatedView);

            return(queryRewriter);
        }
        // requires: schema refers to C-side or S-side schema for the cells
        // inside this. if schema.IsQueryView is true, the left side of cells refers
        // to the C side (and vice-versa for the right side)
        // effects: Generates the relevant views for the schema side and
        // returns them. If allowMissingAttributes is true and attributes
        // are missing on the schema side, substitutes them with NULL
        // Modifies views to contain the generated views for different
        // extents specified by cells and the the schemaContext
        private ErrorLog GenerateDirectionalViews(ViewTarget viewTarget, CqlIdentifiers identifiers, ViewSet views)
        {
            bool isQueryView = viewTarget == ViewTarget.QueryView;

            // Partition cells by extent.
            KeyToListMap <EntitySetBase, Cell> extentCellMap = GroupCellsByExtent(m_cellGroup, viewTarget);

            // Keep track of the mapping exceptions that we have generated
            ErrorLog errorLog = new ErrorLog();

            // Generate views for each extent
            foreach (EntitySetBase extent in extentCellMap.Keys)
            {
                if (m_config.IsViewTracing)
                {
                    Helpers.StringTraceLine(String.Empty);
                    Helpers.StringTraceLine(String.Empty);
                    Helpers.FormatTraceLine("================= Generating {0} View for: {1} ===========================",
                                            isQueryView ? "Query" : "Update", extent.Name);
                    Helpers.StringTraceLine(String.Empty);
                    Helpers.StringTraceLine(String.Empty);
                }
                try
                {
                    // (1) view generation (checks that extents are fully mapped)
                    QueryRewriter queryRewriter = GenerateDirectionalViewsForExtent(viewTarget, extent, identifiers, views);

                    // (2) validation for update views
                    if (viewTarget == ViewTarget.UpdateView &&
                        m_config.IsValidationEnabled)
                    {
                        if (m_config.IsViewTracing)
                        {
                            Helpers.StringTraceLine(String.Empty);
                            Helpers.StringTraceLine(String.Empty);
                            Helpers.FormatTraceLine("----------------- Validation for generated update view for: {0} -----------------",
                                                    extent.Name);
                            Helpers.StringTraceLine(String.Empty);
                            Helpers.StringTraceLine(String.Empty);
                        }

                        RewritingValidator validator = new RewritingValidator(queryRewriter.ViewgenContext, queryRewriter.BasicView);
                        validator.Validate();
                    }
                }
                catch (InternalMappingException exception)
                {
                    // All exceptions have mapping errors in them
                    Debug.Assert(exception.ErrorLog.Count > 0,
                                 "Incorrectly created mapping exception");
                    errorLog.Merge(exception.ErrorLog);
                }
            }
            return(errorLog);
        }
Exemplo n.º 10
0
 private void CheckForeignKeyConstraints(ErrorLog errorLog)
 {
     foreach (ForeignConstraint foreignKeyConstraint in this.m_foreignKeyConstraints)
     {
         QueryRewriter childRewriter  = (QueryRewriter)null;
         QueryRewriter parentRewriter = (QueryRewriter)null;
         this.m_queryRewriterCache.TryGetValue((EntitySetBase)foreignKeyConstraint.ChildTable, out childRewriter);
         this.m_queryRewriterCache.TryGetValue((EntitySetBase)foreignKeyConstraint.ParentTable, out parentRewriter);
         foreignKeyConstraint.CheckConstraint(this.m_cellGroup, childRewriter, parentRewriter, errorLog, this.m_config);
     }
 }
 internal void CheckConstraint(
     Set <Cell> cells,
     QueryRewriter childRewriter,
     QueryRewriter parentRewriter,
     ErrorLog errorLog,
     ConfigViewGenerator config)
 {
     if (!this.IsConstraintRelevantForCells((IEnumerable <Cell>)cells))
     {
         return;
     }
     if (config.IsNormalTracing)
     {
         Trace.WriteLine(string.Empty);
         Trace.WriteLine(string.Empty);
         Trace.Write("Checking: ");
         Trace.WriteLine((object)this);
     }
     if (childRewriter == null && parentRewriter == null)
     {
         return;
     }
     if (childRewriter == null)
     {
         ErrorLog.Record record = new ErrorLog.Record(ViewGenErrorCode.ForeignKeyMissingTableMapping, Strings.ViewGen_Foreign_Key_Missing_Table_Mapping((object)this.ToUserString(), (object)this.ChildTable.Name), (IEnumerable <LeftCellWrapper>)parentRewriter.UsedCells, string.Empty);
         errorLog.AddEntry(record);
     }
     else if (parentRewriter == null)
     {
         ErrorLog.Record record = new ErrorLog.Record(ViewGenErrorCode.ForeignKeyMissingTableMapping, Strings.ViewGen_Foreign_Key_Missing_Table_Mapping((object)this.ToUserString(), (object)this.ParentTable.Name), (IEnumerable <LeftCellWrapper>)childRewriter.UsedCells, string.Empty);
         errorLog.AddEntry(record);
     }
     else
     {
         if (this.CheckIfConstraintMappedToForeignKeyAssociation(childRewriter, parentRewriter, cells))
         {
             return;
         }
         int count = errorLog.Count;
         if (this.IsForeignKeySuperSetOfPrimaryKeyInChildTable())
         {
             this.GuaranteeForeignKeyConstraintInCSpace(childRewriter, parentRewriter, errorLog);
         }
         else
         {
             this.GuaranteeMappedRelationshipForForeignKey(childRewriter, parentRewriter, (IEnumerable <Cell>)cells, errorLog, config);
         }
         if (count != errorLog.Count)
         {
             return;
         }
         this.CheckForeignKeyColumnOrder(cells, errorLog);
     }
 }
Exemplo n.º 12
0
 private void CheckForeignKeyConstraints(ErrorLog errorLog)
 {
     foreach (var constraint in m_foreignKeyConstraints)
     {
         QueryRewriter childRewriter  = null;
         QueryRewriter parentRewriter = null;
         m_queryRewriterCache.TryGetValue(constraint.ChildTable, out childRewriter);
         m_queryRewriterCache.TryGetValue(constraint.ParentTable, out parentRewriter);
         constraint.CheckConstraint(m_cellGroup, childRewriter, parentRewriter, errorLog, m_config);
     }
 }
        /// <summary>
        /// Parameters
        /// </summary>
        public override Bundle Query(NameValueCollection parameters)
        {
            if (parameters == null)
            {
                this.m_tracer.TraceError(nameof(parameters));
                throw new ArgumentNullException(nameof(parameters), this.m_localizationService.GetString("error.type.ArgumentNullException"));
            }

            Core.Model.Query.NameValueCollection hdsiQuery = null;
            var query = QueryRewriter.RewriteFhirQuery(typeof(Observation), typeof(Core.Model.Acts.Observation), parameters, out hdsiQuery);

            // Do the query
            var totalResults = 0;

            IEnumerable <Core.Model.Acts.Observation> hdsiResults = null;

            if (parameters["value-concept"] != null)
            {
                var predicate = QueryExpressionParser.BuildLinqExpression <CodedObservation>(hdsiQuery);
                hdsiResults = this.QueryEx(predicate, query.QueryId, query.Start, query.Quantity, out totalResults).OfType <Core.Model.Acts.Observation>();
            }
            else if (parameters["value-quantity"] != null)
            {
                var predicate = QueryExpressionParser.BuildLinqExpression <QuantityObservation>(hdsiQuery);
                hdsiResults = this.QueryEx(predicate, query.QueryId, query.Start, query.Quantity, out totalResults).OfType <Core.Model.Acts.Observation>();
            }
            else
            {
                var predicate = QueryExpressionParser.BuildLinqExpression <Core.Model.Acts.Observation>(hdsiQuery);
                hdsiResults = this.Query(predicate, query.QueryId, query.Start, query.Quantity, out totalResults);
            }

            // Return FHIR query result
            var retVal = new FhirQueryResult("Observation")
            {
                Results = hdsiResults.Select(this.MapToFhir).Select(o => new Bundle.EntryComponent
                {
                    Resource = o,
                    Search   = new Bundle.SearchComponent
                    {
                        Mode = Bundle.SearchEntryMode.Match
                    }
                }).ToList(),
                Query        = query,
                TotalResults = totalResults
            };

            base.ProcessIncludes(hdsiResults, parameters, retVal);

            return(ExtensionUtil.ExecuteBeforeSendResponseBehavior(TypeRestfulInteraction.SearchType, this.ResourceType, MessageUtil.CreateBundle(retVal, Bundle.BundleType.Searchset)) as Bundle);
        }
        private bool CheckIfConstraintMappedToForeignKeyAssociation(
            QueryRewriter childRewriter,
            QueryRewriter parentRewriter,
            Set <Cell> cells)
        {
            ViewgenContext            viewgenContext1 = childRewriter.ViewgenContext;
            ViewgenContext            viewgenContext2 = parentRewriter.ViewgenContext;
            List <Set <EdmProperty> > source1         = new List <Set <EdmProperty> >();
            List <Set <EdmProperty> > source2         = new List <Set <EdmProperty> >();

            foreach (Cell cell in cells)
            {
                if (cell.CQuery.Extent.BuiltInTypeKind != BuiltInTypeKind.AssociationSet)
                {
                    Set <EdmProperty> cslotsForTableColumns1 = cell.GetCSlotsForTableColumns(this.ChildColumns);
                    if (cslotsForTableColumns1 != null && cslotsForTableColumns1.Count != 0)
                    {
                        source1.Add(cslotsForTableColumns1);
                    }
                    Set <EdmProperty> cslotsForTableColumns2 = cell.GetCSlotsForTableColumns(this.ParentColumns);
                    if (cslotsForTableColumns2 != null && cslotsForTableColumns2.Count != 0)
                    {
                        source2.Add(cslotsForTableColumns2);
                    }
                }
            }
            if (source1.Count != 0 && source2.Count != 0)
            {
                foreach (AssociationType associationType in viewgenContext1.EntityContainerMapping.EdmEntityContainer.BaseEntitySets.OfType <AssociationSet>().Where <AssociationSet>((Func <AssociationSet, bool>)(it => it.ElementType.IsForeignKey)).Select <AssociationSet, AssociationType>((Func <AssociationSet, AssociationType>)(it => it.ElementType)))
                {
                    ReferentialConstraint            refConstraint = associationType.ReferentialConstraints.FirstOrDefault <ReferentialConstraint>();
                    IEnumerable <Set <EdmProperty> > source3       = source1.Where <Set <EdmProperty> >((Func <Set <EdmProperty>, bool>)(it => it.SetEquals(new Set <EdmProperty>((IEnumerable <EdmProperty>)refConstraint.ToProperties))));
                    IEnumerable <Set <EdmProperty> > source4       = source2.Where <Set <EdmProperty> >((Func <Set <EdmProperty>, bool>)(it => it.SetEquals(new Set <EdmProperty>((IEnumerable <EdmProperty>)refConstraint.FromProperties))));
                    if (source3.Count <Set <EdmProperty> >() != 0 && source4.Count <Set <EdmProperty> >() != 0)
                    {
                        foreach (IEnumerable <EdmProperty> properties1_1 in source4)
                        {
                            Set <int> propertyIndexes = ForeignConstraint.GetPropertyIndexes(properties1_1, refConstraint.FromProperties);
                            foreach (IEnumerable <EdmProperty> properties1_2 in source3)
                            {
                                if (ForeignConstraint.GetPropertyIndexes(properties1_2, refConstraint.ToProperties).SequenceEqual <int>((IEnumerable <int>)propertyIndexes))
                                {
                                    return(true);
                                }
                            }
                        }
                    }
                }
            }
            return(false);
        }
        private static bool CheckConstraintWhenOnlyParentMapped(
            AssociationSet assocSet,
            AssociationEndMember endMember,
            QueryRewriter childRewriter,
            QueryRewriter parentRewriter)
        {
            ViewgenContext viewgenContext1 = childRewriter.ViewgenContext;
            ViewgenContext viewgenContext2 = parentRewriter.ViewgenContext;
            CellTreeNode   basicView       = parentRewriter.BasicView;
            RoleBoolean    roleBoolean     = new RoleBoolean(assocSet.AssociationSetEnds[endMember.Name]);
            BoolExpression whereClause     = basicView.RightFragmentQuery.Condition.Create((BoolLiteral)roleBoolean);
            FragmentQuery  q1 = FragmentQuery.Create((IEnumerable <MemberPath>)basicView.RightFragmentQuery.Attributes, whereClause);

            return(FragmentQueryProcessor.Merge(viewgenContext1.RightFragmentQP, viewgenContext2.RightFragmentQP).IsContainedIn(q1, basicView.RightFragmentQuery));
        }
Exemplo n.º 16
0
        /// <summary>
        /// Queries for a specified resource.
        /// </summary>
        /// <param name="parameters">The parameters.</param>
        /// <returns>Returns the FHIR query result containing the results of the query.</returns>
        /// <exception cref="System.ArgumentNullException">parameters</exception>
        public virtual Bundle Query(System.Collections.Specialized.NameValueCollection parameters)
        {
            if (parameters == null)
            {
                this.m_traceSource.TraceError($"Argument {nameof(parameters)} null or empty");
                throw new ArgumentNullException(this.m_localizationService.GetString("error.type.ArgumentNullException"));
            }

            Core.Model.Query.NameValueCollection hdsiQuery = null;
            FhirQuery query = QueryRewriter.RewriteFhirQuery(typeof(TFhirResource), typeof(TModel), parameters, out hdsiQuery);

            // Do the query
            int totalResults = 0;
            var predicate    = QueryExpressionParser.BuildLinqExpression <TModel>(hdsiQuery);
            var hdsiResults  = this.Query(predicate, query.QueryId, query.Start, query.Quantity, out totalResults);

            var auth = AuthenticationContext.Current;

            // Return FHIR query result
            if (Environment.ProcessorCount > 4)
            {
                hdsiResults = hdsiResults.AsParallel().AsOrdered();
            }

            var retVal = new FhirQueryResult(typeof(TFhirResource).Name)
            {
                Results = hdsiResults.Select(o =>
                {
                    using (AuthenticationContext.EnterContext(auth.Principal))
                    {
                        return(new Bundle.EntryComponent()
                        {
                            Resource = this.MapToFhir(o),
                            Search = new Bundle.SearchComponent()
                            {
                                Mode = Bundle.SearchEntryMode.Match
                            }
                        });
                    }
                }).ToList(),
                Query        = query,
                TotalResults = totalResults
            };

            this.ProcessIncludes(hdsiResults, parameters, retVal);

            return(ExtensionUtil.ExecuteBeforeSendResponseBehavior(TypeRestfulInteraction.SearchType, this.ResourceType, MessageUtil.CreateBundle(retVal, Bundle.BundleType.Searchset)) as Bundle);
        }
Exemplo n.º 17
0
        private ErrorLog GenerateDirectionalViews(
            ViewTarget viewTarget,
            CqlIdentifiers identifiers,
            KeyToListMap <EntitySetBase, GeneratedView> views)
        {
            bool flag = viewTarget == ViewTarget.QueryView;
            KeyToListMap <EntitySetBase, Cell> keyToListMap = ViewGenerator.GroupCellsByExtent((IEnumerable <Cell>) this.m_cellGroup, viewTarget);
            ErrorLog errorLog = new ErrorLog();

            foreach (EntitySetBase key in keyToListMap.Keys)
            {
                if (this.m_config.IsViewTracing)
                {
                    Helpers.StringTraceLine(string.Empty);
                    Helpers.StringTraceLine(string.Empty);
                    Helpers.FormatTraceLine("================= Generating {0} View for: {1} ===========================", flag ? (object)"Query" : (object)"Update", (object)key.Name);
                    Helpers.StringTraceLine(string.Empty);
                    Helpers.StringTraceLine(string.Empty);
                }
                try
                {
                    QueryRewriter directionalViewsForExtent = this.GenerateDirectionalViewsForExtent(viewTarget, key, identifiers, views);
                    if (viewTarget == ViewTarget.UpdateView)
                    {
                        if (this.m_config.IsValidationEnabled)
                        {
                            if (this.m_config.IsViewTracing)
                            {
                                Helpers.StringTraceLine(string.Empty);
                                Helpers.StringTraceLine(string.Empty);
                                Helpers.FormatTraceLine("----------------- Validation for generated update view for: {0} -----------------", (object)key.Name);
                                Helpers.StringTraceLine(string.Empty);
                                Helpers.StringTraceLine(string.Empty);
                            }
                            new RewritingValidator(directionalViewsForExtent.ViewgenContext, directionalViewsForExtent.BasicView).Validate();
                        }
                    }
                }
                catch (InternalMappingException ex)
                {
                    errorLog.Merge(ex.ErrorLog);
                }
            }
            return(errorLog);
        }
Exemplo n.º 18
0
 /// <summary>
 /// Get definition for the specified resource
 /// </summary>
 public virtual ResourceComponent GetResourceDefinition()
 {
     return(new ResourceComponent()
     {
         ConditionalCreate = false,
         ConditionalUpdate = true,
         ConditionalDelete = ConditionalDeleteStatus.NotSupported,
         ReadHistory = true,
         UpdateCreate = true,
         Versioning = typeof(IVersionedEntity).IsAssignableFrom(typeof(TModel)) ?
                      ResourceVersionPolicy.Versioned :
                      ResourceVersionPolicy.NoVersion,
         Interaction = this.GetInteractions().ToList(),
         SearchParam = QueryRewriter.GetSearchParams <TFhirResource, TModel>().ToList(),
         Type = Hl7.Fhir.Utility.EnumUtility.ParseLiteral <ResourceType>(typeof(TFhirResource).GetCustomAttribute <FhirTypeAttribute>().Name),
         Profile = $"/StructureDefinition/SanteDB/_history/{Assembly.GetEntryAssembly().GetName().Version}"
     });
 }
Exemplo n.º 19
0
        private QueryRewriter GenerateViewsForExtentAndType(
            EdmType generatedType,
            ViewgenContext context,
            CqlIdentifiers identifiers,
            KeyToListMap <EntitySetBase, GeneratedView> views,
            ViewGenMode mode)
        {
            QueryRewriter queryRewriter = new QueryRewriter(generatedType, context, mode);

            queryRewriter.GenerateViewComponents();
            CellTreeNode basicView = queryRewriter.BasicView;

            if (this.m_config.IsNormalTracing)
            {
                Helpers.StringTrace("Basic View: ");
                Helpers.StringTraceLine(basicView.ToString());
            }
            CellTreeNode simplifiedView = ViewGenerator.GenerateSimplifiedView(basicView, queryRewriter.UsedCells);

            if (this.m_config.IsNormalTracing)
            {
                Helpers.StringTraceLine(string.Empty);
                Helpers.StringTrace("Simplified View: ");
                Helpers.StringTraceLine(simplifiedView.ToString());
            }
            CqlGenerator       cqlGenerator = new CqlGenerator(simplifiedView, queryRewriter.CaseStatements, identifiers, context.MemberMaps.ProjectedSlotMap, queryRewriter.UsedCells.Count, queryRewriter.TopLevelWhereClause, this.m_entityContainerMapping.StorageMappingItemCollection);
            string             eSQL;
            DbQueryCommandTree commandTree;

            if (this.m_config.GenerateEsql)
            {
                eSQL        = cqlGenerator.GenerateEsql();
                commandTree = (DbQueryCommandTree)null;
            }
            else
            {
                eSQL        = (string)null;
                commandTree = cqlGenerator.GenerateCqt();
            }
            GeneratedView generatedView = GeneratedView.CreateGeneratedView(context.Extent, generatedType, commandTree, eSQL, this.m_entityContainerMapping.StorageMappingItemCollection, this.m_config);

            views.Add(context.Extent, generatedView);
            return(queryRewriter);
        }
Exemplo n.º 20
0
        // effects: Generates a view for an extent "extent" that belongs to
        // schema "schema". extentCells are the cells for this extent.
        // Adds the view corresponding to the extent to "views"
        private QueryRewriter GenerateDirectionalViewsForExtent(
            ViewTarget viewTarget, EntitySetBase extent, CqlIdentifiers identifiers, ViewSet views)
        {
            // First normalize the cells in terms of multiconstants, etc
            // and then generate the view for the extent
            var           context       = CreateViewgenContext(extent, viewTarget, identifiers);
            QueryRewriter queryRewriter = null;

            if (m_config.GenerateViewsForEachType)
            {
                // generate views for each OFTYPE(Extent, Type) combination
                foreach (
                    var type in
                    MetadataHelper.GetTypeAndSubtypesOf(
                        extent.ElementType, m_entityContainerMapping.StorageMappingItemCollection.EdmItemCollection, false
                        /*includeAbstractTypes*/))
                {
                    if (m_config.IsViewTracing &&
                        false == type.Equals(extent.ElementType))
                    {
                        Helpers.FormatTraceLine("CQL View for {0} and type {1}", extent.Name, type.Name);
                    }
                    queryRewriter = GenerateViewsForExtentAndType(type, context, identifiers, views, ViewGenMode.OfTypeViews);
                }
            }
            else
            {
                // generate the view for Extent only
                queryRewriter = GenerateViewsForExtentAndType(extent.ElementType, context, identifiers, views, ViewGenMode.OfTypeViews);
            }
            if (viewTarget == ViewTarget.QueryView)
            {
                m_config.SetTimeForFinishedActivity(PerfType.QueryViews);
            }
            else
            {
                m_config.SetTimeForFinishedActivity(PerfType.UpdateViews);
            }

            // cache this rewriter (and context inside it) for future use in FK checking
            m_queryRewriterCache[extent] = queryRewriter;
            return(queryRewriter);
        }
        // according to case statements, where WHEN ... THEN was replaced by ELSE
        private Dictionary <MemberValueBinding, CellTreeNode> CreateMemberValueTrees(bool complementElse)
        {
            var memberValueTrees = new Dictionary <MemberValueBinding, CellTreeNode>();

            foreach (var column in _domainMap.ConditionMembers(_viewgenContext.Extent))
            {
                var domain = new List <Constant>(_domainMap.GetDomain(column));

                // all domain members but the last
                var memberCover = new OpCellTreeNode(_viewgenContext, CellTreeOpType.Union);
                for (var i = 0; i < domain.Count; i++)
                {
                    var domainValue          = domain[i];
                    var memberValue          = new MemberValueBinding(column, domainValue);
                    var memberConditionQuery = QueryRewriter.CreateMemberConditionQuery(column, domainValue, _keyAttributes, _domainMap);
                    Tile <FragmentQuery> rewriting;
                    if (_viewgenContext.TryGetCachedRewriting(memberConditionQuery, out rewriting))
                    {
                        // turn rewriting into a cell tree
                        var cellTreeNode = QueryRewriter.TileToCellTree(rewriting, _viewgenContext);
                        memberValueTrees[memberValue] = cellTreeNode;
                        // collect a union of all domain constants but the last
                        if (i < domain.Count - 1)
                        {
                            memberCover.Add(cellTreeNode);
                        }
                    }
                    else
                    {
                        Debug.Fail(String.Format(CultureInfo.InvariantCulture, "No cached rewriting for {0}={1}", column, domainValue));
                    }
                }

                if (complementElse && domain.Count > 1)
                {
                    var lastDomainValue = domain[domain.Count - 1];
                    var lastMemberValue = new MemberValueBinding(column, lastDomainValue);
                    memberValueTrees[lastMemberValue] = new OpCellTreeNode(_viewgenContext, CellTreeOpType.LASJ, _basicView, memberCover);
                }
            }

            return(memberValueTrees);
        }
Exemplo n.º 22
0
        /// <summary>
        /// Parameters
        /// </summary>
        public override FhirQueryResult Query(System.Collections.Specialized.NameValueCollection parameters)
        {
            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }

            Core.Model.Query.NameValueCollection hdsiQuery = null;
            FhirQuery query = QueryRewriter.RewriteFhirQuery <SanteDB.Messaging.FHIR.Resources.Observation, Core.Model.Acts.Observation>(parameters, out hdsiQuery);

            // Do the query
            int totalResults = 0;

            IEnumerable <Core.Model.Acts.Observation> hdsiResults = null;

            if (parameters["value-concept"] != null)
            {
                var predicate = QueryExpressionParser.BuildLinqExpression <Core.Model.Acts.CodedObservation>(hdsiQuery);
                hdsiResults = this.QueryEx <Core.Model.Acts.CodedObservation>(predicate, query.QueryId, query.Start, query.Quantity, out totalResults).OfType <Core.Model.Acts.Observation>();
            }
            else if (parameters["value-quantity"] != null)
            {
                var predicate = QueryExpressionParser.BuildLinqExpression <Core.Model.Acts.QuantityObservation>(hdsiQuery);
                hdsiResults = this.QueryEx <Core.Model.Acts.QuantityObservation>(predicate, query.QueryId, query.Start, query.Quantity, out totalResults).OfType <Core.Model.Acts.Observation>();
            }
            else
            {
                var predicate = QueryExpressionParser.BuildLinqExpression <Core.Model.Acts.Observation>(hdsiQuery);
                hdsiResults = this.Query(predicate, query.QueryId, query.Start, query.Quantity, out totalResults);
            }


            var restOperationContext = RestOperationContext.Current;

            // Return FHIR query result
            return(new FhirQueryResult()
            {
                Results = hdsiResults.AsParallel().Select(o => this.MapToFhir(o, restOperationContext)).OfType <ResourceBase>().ToList(),
                Query = query,
                TotalResults = totalResults
            });
        }
Exemplo n.º 23
0
        // requires: IsForeignKeySuperSetOfPrimaryKeyInChildTable() is false
        // and primaryKeys of ChildTable are not mapped in cell. cell
        // corresponds to an association set. parentSet is the set
        // corresponding to the end that we are looking at
        // effects: Checks if the constraint is correctly maintained in
        // C-space via an association set (being a subset of the
        // corresponding entitySet)
        private static bool CheckConstraintWhenOnlyParentMapped(
            AssociationSet assocSet, AssociationEndMember endMember,
            QueryRewriter childRewriter, QueryRewriter parentRewriter)
        {
            var childContext  = childRewriter.ViewgenContext;
            var parentContext = parentRewriter.ViewgenContext;

            var pNode = parentRewriter.BasicView;

            Debug.Assert(pNode != null);

            var endRoleBoolean = new RoleBoolean(assocSet.AssociationSetEnds[endMember.Name]);
            // use query in pNode as a factory to create a bool expression for the endRoleBoolean
            var endCondition = pNode.RightFragmentQuery.Condition.Create(endRoleBoolean);
            var cNodeQuery   = FragmentQuery.Create(pNode.RightFragmentQuery.Attributes, endCondition);

            var qp        = FragmentQueryProcessor.Merge(childContext.RightFragmentQP, parentContext.RightFragmentQP);
            var cImpliesP = qp.IsContainedIn(cNodeQuery, pNode.RightFragmentQuery);

            return(cImpliesP);
        }
Exemplo n.º 24
0
 /// <summary>
 /// Get definition for the specified resource
 /// </summary>
 public virtual SanteDB.Messaging.FHIR.Backbone.ResourceDefinition GetResourceDefinition()
 {
     return(new SanteDB.Messaging.FHIR.Backbone.ResourceDefinition()
     {
         ConditionalCreate = false,
         ConditionalUpdate = true,
         ConditionalDelete = SanteDB.Messaging.FHIR.Backbone.ConditionalDeleteStatus.NotSupported,
         ReadHistory = true,
         UpdateCreate = true,
         Versioning = typeof(IVersionedEntity).IsAssignableFrom(typeof(TModel)) ?
                      SanteDB.Messaging.FHIR.Backbone.ResourceVersionPolicy.Versioned :
                      SanteDB.Messaging.FHIR.Backbone.ResourceVersionPolicy.NonVersioned,
         Interaction = this.GetInteractions().ToList(),
         SearchParams = QueryRewriter.GetSearchParams <TFhirResource, TModel>().ToList(),
         Type = typeof(TFhirResource).GetCustomAttribute <XmlRootAttribute>().ElementName,
         Profile = new Reference <StructureDefinition>()
         {
             ReferenceUrl = $"/StructureDefinition/SanteDB/_history/{Assembly.GetEntryAssembly().GetName().Version}"
         }
     });
 }
        // requires: IsForeignKeySuperSetOfPrimaryKeyInChildTable() is false
        // and primaryKeys of ChildTable are not mapped in cell. cell
        // corresponds to an association set. parentSet is the set
        // corresponding to the end that we are looking at
        // effects: Checks if the constraint is correctly maintained in
        // C-space via an association set (being a subset of the
        // corresponding entitySet)
        private bool CheckConstraintWhenOnlyParentMapped(Cell cell, EntitySet parentSet, AssociationSet assocSet, AssociationEndMember endMember,
                                                         QueryRewriter childRewriter, QueryRewriter parentRewriter,
                                                         ConfigViewGenerator config)
        {
            ViewgenContext childContext  = childRewriter.ViewgenContext;
            ViewgenContext parentContext = parentRewriter.ViewgenContext;

            CellTreeNode pNode = parentRewriter.BasicView;

            Debug.Assert(pNode != null);

            RoleBoolean endRoleBoolean = new RoleBoolean(assocSet.AssociationSetEnds[endMember.Name]);
            // use query in pNode as a factory to create a bool expression for the endRoleBoolean
            BoolExpression endCondition = pNode.RightFragmentQuery.Condition.Create(endRoleBoolean);
            FragmentQuery  cNodeQuery   = FragmentQuery.Create(pNode.RightFragmentQuery.Attributes, endCondition);

            FragmentQueryProcessor qp = FragmentQueryProcessor.Merge(childContext.RightFragmentQP, parentContext.RightFragmentQP);
            bool cImpliesP            = qp.IsContainedIn(cNodeQuery, pNode.RightFragmentQuery);

            return(cImpliesP);
        }
        private void GuaranteeForeignKeyConstraintInCSpace(
            QueryRewriter childRewriter,
            QueryRewriter parentRewriter,
            ErrorLog errorLog)
        {
            ViewgenContext viewgenContext1 = childRewriter.ViewgenContext;
            ViewgenContext viewgenContext2 = parentRewriter.ViewgenContext;
            CellTreeNode   basicView1      = childRewriter.BasicView;
            CellTreeNode   basicView2      = parentRewriter.BasicView;

            if (FragmentQueryProcessor.Merge(viewgenContext1.RightFragmentQP, viewgenContext2.RightFragmentQP).IsContainedIn(basicView1.RightFragmentQuery, basicView2.RightFragmentQuery))
            {
                return;
            }
            LeftCellWrapper.GetExtentListAsUserString((IEnumerable <LeftCellWrapper>)basicView1.GetLeaves());
            LeftCellWrapper.GetExtentListAsUserString((IEnumerable <LeftCellWrapper>)basicView2.GetLeaves());
            string message            = Strings.ViewGen_Foreign_Key_Not_Guaranteed_InCSpace((object)this.ToUserString());
            Set <LeftCellWrapper> set = new Set <LeftCellWrapper>((IEnumerable <LeftCellWrapper>)basicView2.GetLeaves());

            set.AddRange((IEnumerable <LeftCellWrapper>)basicView1.GetLeaves());
            ErrorLog.Record record = new ErrorLog.Record(ViewGenErrorCode.ForeignKeyNotGuaranteedInCSpace, message, (IEnumerable <LeftCellWrapper>)set, string.Empty);
            errorLog.AddEntry(record);
        }
Exemplo n.º 27
0
        private Dictionary <RewritingValidator.MemberValueBinding, CellTreeNode> CreateMemberValueTrees(
            bool complementElse)
        {
            Dictionary <RewritingValidator.MemberValueBinding, CellTreeNode> dictionary = new Dictionary <RewritingValidator.MemberValueBinding, CellTreeNode>();

            foreach (MemberPath conditionMember in this._domainMap.ConditionMembers(this._viewgenContext.Extent))
            {
                List <Constant> constantList   = new List <Constant>(this._domainMap.GetDomain(conditionMember));
                OpCellTreeNode  opCellTreeNode = new OpCellTreeNode(this._viewgenContext, CellTreeOpType.Union);
                for (int index1 = 0; index1 < constantList.Count; ++index1)
                {
                    Constant domainValue = constantList[index1];
                    RewritingValidator.MemberValueBinding index2 = new RewritingValidator.MemberValueBinding(conditionMember, domainValue);
                    Tile <FragmentQuery> rewriting;
                    if (this._viewgenContext.TryGetCachedRewriting(QueryRewriter.CreateMemberConditionQuery(conditionMember, domainValue, this._keyAttributes, this._domainMap), out rewriting))
                    {
                        CellTreeNode cellTree = QueryRewriter.TileToCellTree(rewriting, this._viewgenContext);
                        dictionary[index2] = cellTree;
                        if (index1 < constantList.Count - 1)
                        {
                            opCellTreeNode.Add(cellTree);
                        }
                    }
                }
                if (complementElse && constantList.Count > 1)
                {
                    Constant constant = constantList[constantList.Count - 1];
                    RewritingValidator.MemberValueBinding index = new RewritingValidator.MemberValueBinding(conditionMember, constant);
                    dictionary[index] = (CellTreeNode) new OpCellTreeNode(this._viewgenContext, CellTreeOpType.LASJ, new CellTreeNode[2]
                    {
                        this._basicView,
                        (CellTreeNode)opCellTreeNode
                    });
                }
            }
            return(dictionary);
        }
Exemplo n.º 28
0
        /// <summary>
        /// Queries for a specified resource.
        /// </summary>
        /// <param name="parameters">The parameters.</param>
        /// <returns>Returns the FHIR query result containing the results of the query.</returns>
        /// <exception cref="System.ArgumentNullException">parameters</exception>
        public virtual FhirQueryResult Query(System.Collections.Specialized.NameValueCollection parameters)
        {
            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }

            Core.Model.Query.NameValueCollection hdsiQuery = null;
            FhirQuery query = QueryRewriter.RewriteFhirQuery <TFhirResource, TModel>(parameters, out hdsiQuery);

            // Do the query
            int totalResults         = 0;
            var predicate            = QueryExpressionParser.BuildLinqExpression <TModel>(hdsiQuery);
            var hdsiResults          = this.Query(predicate, query.QueryId, query.Start, query.Quantity, out totalResults);
            var restOperationContext = RestOperationContext.Current;

            var auth = AuthenticationContext.Current;

            // Return FHIR query result
            return(new FhirQueryResult()
            {
                Results = hdsiResults.AsParallel().Select(o => {
                    try
                    {
                        AuthenticationContext.Current = auth;
                        return this.MapToFhir(o, restOperationContext);
                    }
                    finally
                    {
                        AuthenticationContext.Current = new AuthenticationContext(AuthenticationContext.AnonymousPrincipal);
                    }
                }).OfType <ResourceBase>().ToList(),
                Query = query,
                TotalResults = totalResults
            });
        }
Exemplo n.º 29
0
        private bool CheckIfConstraintMappedToForeignKeyAssociation(
            QueryRewriter childRewriter, QueryRewriter parentRewriter,
            Set <Cell> cells)
        {
            var childContext  = childRewriter.ViewgenContext;
            var parentContext = parentRewriter.ViewgenContext;

            //First collect the sets of properties that the principal and dependant ends of this FK
            //are mapped to in the Edm side.
            var childPropertiesSet  = new List <Set <EdmProperty> >();
            var parentPropertiesSet = new List <Set <EdmProperty> >();

            foreach (var cell in cells)
            {
                if (cell.CQuery.Extent.BuiltInTypeKind
                    != BuiltInTypeKind.AssociationSet)
                {
                    var childProperties = cell.GetCSlotsForTableColumns(ChildColumns);
                    if ((childProperties != null) &&
                        (childProperties.Count != 0))
                    {
                        childPropertiesSet.Add(childProperties);
                    }
                    var parentProperties = cell.GetCSlotsForTableColumns(ParentColumns);
                    if ((parentProperties != null) &&
                        (parentProperties.Count != 0))
                    {
                        parentPropertiesSet.Add(parentProperties);
                    }
                }
            }

            //Now Check if the properties on the Edm side are connected via an FK relationship.
            if ((childPropertiesSet.Count != 0) &&
                (parentPropertiesSet.Count != 0))
            {
                var foreignKeyAssociations =
                    childContext.EntityContainerMapping.EdmEntityContainer.BaseEntitySets.OfType <AssociationSet>().Where(
                        it => it.ElementType.IsForeignKey).Select(it => it.ElementType);
                foreach (var association in foreignKeyAssociations)
                {
                    var refConstraint = association.ReferentialConstraints.FirstOrDefault();
                    //We need to check to see if the dependent properties that were mapped from S side are present as
                    //dependant properties of this ref constraint on the Edm side. We need to do the same for principal side but
                    //we can not enforce equality since the order of the properties participating in the constraint on the S side and
                    //C side could be different. This is OK as long as they are mapped appropriately. We also can not use Existance as a sufficient
                    //condition since it will allow invalid mapping where FK columns could have been flipped when mapping to the Edm side. So
                    //we make sure that the index of the properties in the principal and dependant are same on the Edm side even if they are in
                    //different order for ref constraints for Edm and store side.
                    var childRefPropertiesCollection =
                        childPropertiesSet.Where(it => it.SetEquals(new Set <EdmProperty>(refConstraint.ToProperties)));
                    var parentRefPropertiesCollection =
                        parentPropertiesSet.Where(it => it.SetEquals(new Set <EdmProperty>(refConstraint.FromProperties)));
                    if ((childRefPropertiesCollection.Count() != 0 && parentRefPropertiesCollection.Count() != 0))
                    {
                        foreach (var parentRefProperties in parentRefPropertiesCollection)
                        {
                            var parentIndexes = GetPropertyIndexes(parentRefProperties, refConstraint.FromProperties);
                            foreach (var childRefProperties in childRefPropertiesCollection)
                            {
                                var childIndexes = GetPropertyIndexes(childRefProperties, refConstraint.ToProperties);

                                if (childIndexes.SequenceEqual(parentIndexes))
                                {
                                    return(true);
                                }
                            }
                        }
                    }
                }
            }
            return(false);
        }
Exemplo n.º 30
0
        // effects: Ensures that there is a relationship mapped into the C-space for some cell in m_cellGroup. Else
        // adds an error to errorLog
        private void GuaranteeMappedRelationshipForForeignKey(
            QueryRewriter childRewriter, QueryRewriter parentRewriter,
            IEnumerable <Cell> cells,
            ErrorLog errorLog, ConfigViewGenerator config)
        {
            var childContext  = childRewriter.ViewgenContext;
            var parentContext = parentRewriter.ViewgenContext;

            // Find a cell where this foreign key is mapped as a relationship
            var prefix           = new MemberPath(ChildTable);
            var primaryKey       = ExtentKey.GetPrimaryKeyForEntityType(prefix, ChildTable.ElementType);
            var primaryKeyFields = primaryKey.KeyFields;
            var foundCell        = false;

            var foundValidParentColumnsForForeignKey = false; //we need to find only one, dont error on any one check being false
            List <ErrorLog.Record> errorListForInvalidParentColumnsForForeignKey = null;

            foreach (var cell in cells)
            {
                if (cell.SQuery.Extent.Equals(ChildTable) == false)
                {
                    continue;
                }

                // The childtable is mapped to a relationship in the C-space in cell
                // Check that all the columns of the foreign key and the primary key in the child table are mapped to some
                // property in the C-space

                var parentEnd = GetRelationEndForColumns(cell, ChildColumns);
                if (parentEnd != null &&
                    CheckParentColumnsForForeignKey(cell, cells, parentEnd, ref errorListForInvalidParentColumnsForForeignKey) == false)
                {
                    // Not an error unless we find no valid case
                    continue;
                }
                else
                {
                    foundValidParentColumnsForForeignKey = true;
                }

                var childEnd = GetRelationEndForColumns(cell, primaryKeyFields);
                Debug.Assert(
                    childEnd == null || parentEnd != childEnd,
                    "Ends are same => PKey and child columns are same - code should gone to other method");
                // Note: If both of them are not-null, they are mapped to the
                // same association set -- since we checked that particular cell

                if (childEnd != null &&
                    parentEnd != null
                    &&
                    FindEntitySetForColumnsMappedToEntityKeys(cells, primaryKeyFields) != null)
                {
                    foundCell = true;
                    CheckConstraintWhenParentChildMapped(cell, errorLog, parentEnd, config);
                    break; // Done processing for the foreign key - either it was mapped correctly or it was not
                }
                else if (parentEnd != null)
                {
                    // At this point, we know cell corresponds to an association set
                    var assocSet  = (AssociationSet)cell.CQuery.Extent;
                    var parentSet = MetadataHelper.GetEntitySetAtEnd(assocSet, parentEnd);
                    foundCell = CheckConstraintWhenOnlyParentMapped(assocSet, parentEnd, childRewriter, parentRewriter);
                    if (foundCell)
                    {
                        break;
                    }
                }
            }

            //CheckParentColumnsForForeignKey has returned no matches, Error.
            if (!foundValidParentColumnsForForeignKey)
            {
                Debug.Assert(
                    errorListForInvalidParentColumnsForForeignKey != null && errorListForInvalidParentColumnsForForeignKey.Count > 0);
                foreach (var errorRecord in errorListForInvalidParentColumnsForForeignKey)
                {
                    errorLog.AddEntry(errorRecord);
                }
                return;
            }

            if (foundCell == false)
            {
                // No cell found -- Declare error
                var message = Strings.ViewGen_Foreign_Key_Missing_Relationship_Mapping(ToUserString());

                IEnumerable <LeftCellWrapper> parentWrappers = GetWrappersFromContext(parentContext, ParentTable);
                IEnumerable <LeftCellWrapper> childWrappers  = GetWrappersFromContext(childContext, ChildTable);
                var bothExtentWrappers =
                    new Set <LeftCellWrapper>(parentWrappers);
                bothExtentWrappers.AddRange(childWrappers);
                var record = new ErrorLog.Record(
                    ViewGenErrorCode.ForeignKeyMissingRelationshipMapping, message, bothExtentWrappers, String.Empty);
                errorLog.AddEntry(record);
            }
        }