Пример #1
0
        QueryComposerCriteriaDTO[] ConvertToQueryComposerCriteria(IEnumerable <CodeImport> codes)
        {
            Guid DiagnosisCodeTermID = new Guid("86110001-4bab-4183-b0ea-a4bc0125a6a7");
            Guid ProcedureCodeTermID = new Guid("f81ae5de-7b35-4d7a-b398-a72200ce7419");

            QueryComposerCriteriaDTO[] export = new QueryComposerCriteriaDTO[codes.Max(c => c.CriteriaIndex + 1)];

            foreach (var criteriaGrouping in codes.GroupBy(c => c.CriteriaIndex))
            {
                List <QueryComposerTermDTO> terms = new List <QueryComposerTermDTO>();
                foreach (var grouping in criteriaGrouping.GroupBy(k => new { k.CodeType, k.NumericCodeType, k.SearchMethodType }))
                {
                    Guid termID;
                    if (grouping.Key.CodeType.StartsWith("DX-", StringComparison.OrdinalIgnoreCase))
                    {
                        termID = DiagnosisCodeTermID;
                    }
                    else if (grouping.Key.CodeType.StartsWith("PX-", StringComparison.OrdinalIgnoreCase))
                    {
                        termID = ProcedureCodeTermID;
                    }
                    else
                    {
                        throw new ArgumentOutOfRangeException("CodeType", grouping.Key.CodeType, string.Format("The CodeType \"{0}\" is invalid, all CodeTypes must start with \"DX-\" or \"PX-\".", grouping.Key.CodeType));
                    }

                    var values = grouping.Select(c => c.Code).Where(c => !string.IsNullOrWhiteSpace(c)).Distinct(StringComparer.OrdinalIgnoreCase);

                    terms.Add(
                        new QueryComposerTermDTO
                    {
                        Operator = DTO.Enums.QueryComposerOperators.And,
                        Type     = termID,
                        Values   = new Dictionary <string, object> {
                            { "Values", new {
                                  CodeType   = grouping.Key.NumericCodeType,
                                  CodeValues = string.Join("; ", values),
                                  grouping.Key.SearchMethodType
                              } }
                        }
                    }
                        );
                }

                var innerCriteria = new QueryComposerCriteriaDTO
                {
                    ID       = DatabaseEx.NewGuid(),
                    Name     = "i_codeterms",
                    Operator = DTO.Enums.QueryComposerOperators.And,
                    Terms    = terms.ToArray(),
                    Type     = DTO.Enums.QueryComposerCriteriaTypes.Paragraph
                };

                export[criteriaGrouping.Key] = new QueryComposerCriteriaDTO {
                    Criteria = new[] { innerCriteria }
                };
            }

            return(export);
        }
        /// <summary>
        /// For all the terms matching the specified termID parse the date ranges into a DateRangeValues object.
        /// </summary>
        /// <param name="paragraph">The paragraph to get the date ranges for.</param>
        /// <param name="termID">The ID of the term containing the date ranges.</param>
        /// <returns></returns>
        public List <Adapters.DateRangeValues> ParagraphDateRanges(QueryComposerCriteriaDTO paragraph, Guid termID)
        {
            var terms = paragraph.FlattenCriteriaToTerms().Where(t => t.Type == termID).ToArray();
            List <Adapters.DateRangeValues> ranges = new List <Adapters.DateRangeValues>();

            if (terms != null && terms.Length > 0)
            {
                ranges.AddRange(terms.Select(t => Adapters.AdapterHelpers.ParseDateRangeValues(t)).Where(t => t.HasValue));
            }
            return(ranges);
        }
Пример #3
0
 public IEnumerable <QueryComposerTermDTO> GetAllCriteriaTerms(QueryComposerCriteriaDTO paragraph, Guid termTypeID)
 {
     return(paragraph.FlattenCriteriaToTerms().Where(t => t.Type == termTypeID));
 }
 static IEnumerable <QueryComposerTermDTO> GetAllCriteriaTerms(QueryComposerCriteriaDTO paragraph, Guid termTypeID)
 {
     return(paragraph.Terms.Where(t => t.Type == termTypeID).Concat(paragraph.Criteria.SelectMany(c => c.Terms.Where(t => t.Type == termTypeID))));
 }
Пример #5
0
        IQueryable <Lpp.Dns.DataMart.Model.ESPQueryBuilder.Model.Demographic> ApplyCriteria(QueryComposerCriteriaDTO criteria)
        {
            int?startDate         = null;
            int?endDate           = null;
            var observationPeriod = criteria.Terms.FirstOrDefault(t => t.Type == ModelTermsFactory.ObservationPeriodID);

            if (observationPeriod != null)
            {
                DateTimeOffset date;
                if (DateTimeOffset.TryParse((observationPeriod.Values["Start"] ?? string.Empty).ToString(), out date))
                {
                    startDate = ConvertDateToNumberOfDays(date);
                }
                if (DateTimeOffset.TryParse((observationPeriod.Values["End"] ?? string.Empty).ToString(), out date))
                {
                    endDate = ConvertDateToNumberOfDays(date);
                }
            }

            //determine the smallest age range, ie the max min age, and the min max age.
            int?minAge = DetermineMaxMinValue(GetAllTermsWithinCriteria(criteria, ModelTermsFactory.AgeRangeID).Where(t => t.Values["MinAge"] != null));

            int?maxAge = DetermineMinMaxValue(GetAllTermsWithinCriteria(criteria, ModelTermsFactory.AgeRangeID).Where(t => t.Values["MaxAge"] != null));

            var query = db.Demographics.AsQueryable();

            foreach (var tGroup in (criteria.Criteria.SelectMany(c => c.Terms).Concat(criteria.Terms)).GroupBy(k => k.Type))
            {
                var termID = tGroup.Key;
                if (termID == Lpp.QueryComposer.ModelTermsFactory.AgeRangeID)
                {
                    //applied to the joins as applicable
                }
                else if (termID == Lpp.QueryComposer.ModelTermsFactory.ConditionsID)
                {
                    IEnumerable <string> diseases = tGroup.Select(g => TranslateCondition(g.Values["Condition"])).ToArray();
                    if (diseases.Any())
                    {
                        var d = db.Diseases.AsQueryable();
                        if (startDate.HasValue)
                        {
                            d = d.Where(x => x.Date >= startDate.Value);
                        }
                        if (endDate.HasValue)
                        {
                            d = d.Where(x => x.Date <= endDate.Value);
                        }
                        if (minAge.HasValue)
                        {
                            d = d.Where(x => x.AgeAtDetectYear >= minAge.Value);
                        }
                        else if (maxAge.HasValue)
                        {
                            d = d.Where(x => x.AgeAtDetectYear <= maxAge.Value);
                        }

                        query = from q in query
                                from dd in d.Where(x => x.PatID == q.PatID).DefaultIfEmpty()
                                where diseases.Contains(dd.Condition)
                                select q;
                    }
                }
                else if (termID == Lpp.QueryComposer.ModelTermsFactory.EthnicityID)
                {
                    Expression <Func <Lpp.Dns.DataMart.Model.ESPQueryBuilder.Model.Demographic, bool> > ethnicityExpression = null;
                    foreach (var term in tGroup)
                    {
                        int ethnicity = TranslateEthnicity(term.Values["Ethnicity"]);
                        if (ethnicityExpression == null)
                        {
                            ethnicityExpression = ex => ex.Ethnicity == ethnicity;
                        }
                        else
                        {
                            ethnicityExpression = ethnicityExpression.Or(q => q.Ethnicity == ethnicity);
                        }
                    }

                    if (ethnicityExpression != null)
                    {
                        query = query.Where(ethnicityExpression);
                    }
                }
                else if (termID == Lpp.QueryComposer.ModelTermsFactory.SexID)
                {
                    IEnumerable <string> sexs = tGroup.SelectMany(t => TranslateSex(t.Values["Sex"])).Distinct();
                    if (sexs.Any())
                    {
                        query = query.Where(q => sexs.Contains(q.Sex.ToUpper()));
                    }
                }
                else if (termID == Lpp.QueryComposer.ModelTermsFactory.ICD9DiagnosisCodes3digitID)
                {
                    IEnumerable <string> codes = tGroup.SelectMany(t => (t.Values["Codes"] ?? string.Empty).ToString().Split(',')).Select(t => t.Trim()).Distinct();
                    if (codes.Any())
                    {
                        Expression <Func <Lpp.Dns.DataMart.Model.ESPQueryBuilder.Model.Diagnosis, bool> > icd9Expression = null;
                        foreach (string code in codes)
                        {
                            //TODO:going to have to be terms for 4 and 5 digit as well.
                            if (icd9Expression == null)
                            {
                                icd9Expression = q => q.DxCode3digit.StartsWith(code.ToUpper());
                            }
                            else
                            {
                                icd9Expression = icd9Expression.Or(q => q.DxCode3digit.StartsWith(code.ToUpper()));
                            }
                        }

                        var diag = db.Diagnosis.AsQueryable();
                        if (startDate.HasValue)
                        {
                            diag = diag.Where(x => x.A_Date >= startDate.Value);
                        }
                        if (endDate.HasValue)
                        {
                            diag = diag.Where(x => x.A_Date <= endDate.Value);
                        }
                        if (minAge.HasValue)
                        {
                            diag = diag.Where(x => x.AgeAtEncYear >= minAge.Value);
                        }
                        else if (maxAge.HasValue)
                        {
                            diag = diag.Where(x => x.AgeAtEncYear <= maxAge.Value);
                        }

                        query = diag.Where(icd9Expression).Join(query, o => o.PatID, i => i.PatID, (o, i) => i);
                    }
                }
                else if (termID == Lpp.QueryComposer.ModelTermsFactory.ObservationPeriodID)
                {
                    //observation period is incorporated into the diagnosis and disease joins
                }
                else if (termID == Lpp.QueryComposer.ModelTermsFactory.VisitsID)
                {
                    int visits = tGroup.Where(t => t.Values.ContainsKey("Visits") && t.Values["Visits"] != null).Select(t => Convert.ToInt32(t.Values["Visits"])).Min();

                    var encountersQuery = db.Demographics
                                          .Join(db.Encounters, o => o.PatID, i => i.PatID, (o, i) => new { o.PatID, i.EncounterID, i.AgeGroup5yr, i.AgeGroup10yr, i.A_Date, i.AgeAtEncYear })
                                          .GroupBy(v => new { v.PatID, v.AgeGroup5yr, v.AgeGroup10yr }).Select(v => new EncountersGroupingResult {
                        PatID = v.Key.PatID, AgeGroup5yr = v.Key.AgeGroup5yr, AgeGroup10yr = v.Key.AgeGroup10yr, Count = v.Count()
                    })
                                          .Where(v => v.Count >= visits);

                    query = query.Join(encountersQuery, o => o.PatID, i => i.PatID, (o, i) => o);
                }
                else if (termID == Lpp.QueryComposer.ModelTermsFactory.ZipCodeID)
                {
                    IEnumerable <string> zipCodes = tGroup.SelectMany(t => (t.Values["Codes"] ?? string.Empty).ToString().Split(',')).Select(t => t.Trim()).Distinct();
                    if (zipCodes.Any())
                    {
                        query = query.Where(q => zipCodes.Contains(q.Zip5));
                    }
                }
            }
            return(query);
        }
Пример #6
0
 static IEnumerable <QueryComposerTermDTO> GetAllTermsWithinCriteria(QueryComposerCriteriaDTO criteria, Guid termTypeID)
 {
     return(criteria.Criteria.SelectMany(c => c.Terms.Where(t => t.Type == termTypeID)).Concat(criteria.Terms.Where(t => t.Type == termTypeID)));
 }
Пример #7
0
 protected virtual System.Linq.Expressions.Expression <Func <TBaseQuery, bool> > ApplyVitalsMeasureDateObservationPeriod(QueryComposerCriteriaDTO paragraph, QueryComposerTermDTO term)
 {
     throw new NotImplementedException("The critieria builder for this term has not been implemented.");
 }
Пример #8
0
 protected virtual System.Linq.Expressions.Expression <Func <TBaseQuery, bool> > ApplyTobaccoUseTerm(QueryComposerCriteriaDTO paragraph, QueryComposerTermDTO term)
 {
     throw new NotImplementedException("The critieria builder for this term has not been implemented.");
 }
Пример #9
0
        protected virtual System.Linq.Expressions.Expression <Func <TBaseQuery, bool> > ParseParagraph(QueryComposerCriteriaDTO paragraph)
        {
            //The next operator is used to define the relationship between the current concept with the next concept, if any.
            DTO.Enums.QueryComposerOperators nextOperator = DTO.Enums.QueryComposerOperators.And;

            //Create the paragraph predicate.
            //The predicate is set to TRUE and ANDed with the first concept.
            var paragraphPredicate = PredicateBuilder.True <TBaseQuery>();

            //Process the concepts within the paragraph.
            foreach (var term in paragraph.Terms)
            {
                var termID        = term.Type;
                var termPredicate = PredicateBuilder.True <TBaseQuery>();

                //By default do not apply the term unless it has been registered.
                System.Linq.Expressions.Expression <Func <TBaseQuery, bool> > innerPredicate = null;
                //Parse the term here.
                Func <QueryComposerCriteriaDTO, QueryComposerTermDTO, System.Linq.Expressions.Expression <Func <TBaseQuery, bool> > > action = null;
                if (TermPredicateBuilders.TryGetValue(term.Type, out action))
                {
                    //The term has been registered replace the inner predicate.
                    innerPredicate = action(paragraph, term);
                }

                if (innerPredicate == null)
                {
                    continue;
                }

                termPredicate = termPredicate.And(innerPredicate.Expand());

                if (nextOperator == DTO.Enums.QueryComposerOperators.And)
                {
                    paragraphPredicate = paragraphPredicate.And(termPredicate.Expand());
                }
                else
                {
                    paragraphPredicate = paragraphPredicate.Or(termPredicate.Expand());
                }
                //Handle AndNot and OrNot here.
                nextOperator = term.Operator;
            }

            foreach (var paragraphAction in ParagraphPredicateBuilders)
            {
                //the predicate method is responsible for determining how to apply to the paragraph predicate
                paragraphPredicate = paragraphAction(paragraph, paragraphPredicate);
            }



            //TODO: parse the child criteria and append to the paragraph predicate

            return(paragraphPredicate);
        }