/// <summary>
        /// Find non-deleted concrete data by a keyword which may be included in concrete data name or value.
        /// </summary>
        /// <param name="concreteDataType">Concrete data type.</param>
        /// <param name="query">Keyword included in Name or Value. Null or empty value indicates to query all records in the concrete type.</param>
        /// <param name="limit">Maximum number of returned records.</param>
        /// <returns></returns>
        public Collection<ConcreteDataObject> FindByKeywordJson(string concreteDataType, string query, int limit)
        {
            LinqPredicate predicate = new LinqPredicate("Type=@0 AND DeleteStatus=@1", concreteDataType, DeleteStatus.NotDeleted);

            if (!string.IsNullOrEmpty(query))
                predicate.Add("Name.Contains(@0) OR Value.Contains(@0)", query);

            int recordCount;
            try
            {
                Collection<ConcreteDataObject> results = new Collection<ConcreteDataObject>(concreteDataApi.FindConcreteData(predicate, "Name Asc", 0, limit, out recordCount).ToList());

                return results;
            }
            catch (ArgumentException ex)
            {
                throw new BadRequestException(string.Format(CultureInfo.InvariantCulture, ex.Message));
            }
            catch (BadRequestException bad)
            {
                throw new BadRequestException(string.Format(CultureInfo.InvariantCulture, bad.Message));
            }
            catch (FormatException formatEx)
            {
                throw new BadRequestException(string.Format(CultureInfo.InvariantCulture, formatEx.Message));
            }
            catch (Exception exp)
            {
                Logger.Instance(this).Error(exp);
                throw new InternalServerErrorException();
            }
        }
 public void MergeLinqPredicateWithDuplicateExpressionVariables()
 {
     LinqPredicate predicate = new LinqPredicate("City=@0 AND Height>=@1", "Shanghai", 170);
     predicate.Add("Name.StartsWith(@0) AND Height>=@1", "Eunge", 170);
     Assert.AreEqual(3, predicate.Parameters.Length);
     Assert.AreEqual("Shanghai", predicate.Parameters[0]);
     Assert.AreEqual(170, predicate.Parameters[1]);
     Assert.AreEqual("Eunge", predicate.Parameters[2]);
     Assert.AreEqual("(City=@0 AND Height>=@1) AND (Name.StartsWith(@2) AND Height>=@1)", predicate.Expression);
 }
 public void MergeLinqPredicateWithSequentialParameters()
 {
     LinqPredicate predicate = new LinqPredicate("Name=@0 AND Height=@1", "Eunge", 170);
     predicate.Add("Degree=@0 AND City=@1", "Master", "Shanghai");
     Assert.AreEqual(4, predicate.Parameters.Length);
     Assert.AreEqual("Eunge", predicate.Parameters[0]);
     Assert.AreEqual(170, predicate.Parameters[1]);
     Assert.AreEqual("Master", predicate.Parameters[2]);
     Assert.AreEqual("Shanghai", predicate.Parameters[3]);
     Assert.AreEqual("(Name=@0 AND Height=@1) AND (Degree=@2 AND City=@3)", predicate.Expression);
 }
        /// <summary>
        /// Find all hierarchies which include the query keyword in code or name.
        /// </summary>
        /// <param name="hierarchyType"></param>
        /// <param name="query"></param>
        /// <param name="maxReturnedCount"></param>
        /// <returns></returns>
        public Collection<HierarchyDataObject> FindByKeywordJson(string hierarchyType, string query, int maxReturnedCount)
        {
            if (string.IsNullOrEmpty(hierarchyType))
                throw new BadRequestException(string.Format(CultureInfo.InvariantCulture, Resources.InvalidHierarchyType, hierarchyType));

            try
            {
                int recordCount;
                LinqPredicate predicate = new LinqPredicate("HierarchyType=@0", hierarchyType);
                if (!string.IsNullOrEmpty(query))
                    predicate = predicate.Add("(Code!=null AND Code.StartsWith(@0)) OR (Name!=null AND Name.StartsWith(@0))", query.Replace("-", "").Trim());

                IEnumerable<HierarchyDataObject> hierarchyDataObjects = hierarchyApi.FindHierarchyData(predicate, "Name ASC", 0, maxReturnedCount, out recordCount);

                Collection<HierarchyDataObject> results = new Collection<HierarchyDataObject>();
                IEnumerable<HierarchyDataObject> dummyRootHierarchyDataObjects = FindHierarchyDataObjectWithParentNotExist(hierarchyDataObjects);
                foreach (HierarchyDataObject dummyRootHierarchyDataObject in dummyRootHierarchyDataObjects)
                    HierarchizeHierarchyData(hierarchyDataObjects, dummyRootHierarchyDataObject, results, 0);

                if (results.Count() == 0)
                    return new Collection<HierarchyDataObject>();
                return results;
            }
            catch (ArgumentException ex)
            {
                throw new BadRequestException(string.Format(CultureInfo.InvariantCulture, ex.Message));
            }
            catch (BadRequestException bad)
            {
                throw new BadRequestException(string.Format(CultureInfo.InvariantCulture, bad.Message));
            }
            catch (FormatException formatEx)
            {
                throw new BadRequestException(string.Format(CultureInfo.InvariantCulture, formatEx.Message));
            }
            catch (Exception exp)
            {
                Logger.Instance(this).Error(exp);
                throw new InternalServerErrorException();
            }
        }
 /// <summary>
 /// Concat two linq predicates.
 /// </summary>
 /// <param name="predicate1"></param>
 /// <param name="predicate2"></param>
 /// <returns></returns>
 public static LinqPredicate Concat(LinqPredicate predicate1, LinqPredicate predicate2)
 {
     if (predicate1 != null && predicate2 != null)
         return predicate1.Add(predicate2);
     else if (predicate1 == null && predicate2 != null)
         return predicate2;
     else if (predicate1 != null && predicate2 == null)
         return predicate1;
     else
         return null;
 }
        /// <summary>
        /// Search organizations by a collection of criterias for the authenticated user of request.
        /// </summary>
        /// <param name="domain">Which domain of the searching organizations.</param>
        /// <param name="orgTypeId">Which organization type the searching organizations should belong to.</param>
        /// <param name="q">Keywords for searching.</param>
        /// <param name="sortDirection">Sorting field name, the default sorting field is LastUpdatedDate.</param>
        /// <param name="sortOrder">Sorting order, DESC or ASC, the default sorting order is DESC.</param>
        /// <param name="start">The start organization index of hit to return.</param>
        /// <param name="limit">The limit of returned organizations.</param>
        /// <returns>The query results object includes total hit count, returned records, start and limit.</returns>
        public OrganizationQueryResult SearchJson(string domain, string orgTypeId, string q, string sortDirection, string sortOrder, int start, int limit)
        {
            #region Arguments Validation

            //if (!authenticationContext.Identity.IsAuthenticated)
            //    throw new BadRequestException( "The access is not authenticated.");

            Guid userId = authenticationContext.User.UserId;

            if (string.IsNullOrEmpty(domain))
                throw new BadRequestException(string.Format(CultureInfo.InvariantCulture, Resources.InvalidDomain ));

            if (!platformConfiguration.Domains.Select(d => d.Value).Contains(domain))
                throw new BadRequestException(string.Format(CultureInfo.InvariantCulture, Resources.InvalidDomain ));

            string sortOrderValue = "DESC";
            if (!Kit.IsEmpty(sortOrder))
            {
                sortOrderValue = sortOrder.ToUpperInvariant();
                if (sortOrderValue != "ASC" && sortOrderValue != "DESC")
                    throw new BadRequestException(string.Format(CultureInfo.InvariantCulture, "The value of parameter \"sortOrder\" is invalid. The candidate value are ASC and DESC."));
            }

            string sortFieldValue = "LastUpdatedDate";
            if (!Kit.IsEmpty(sortDirection))
                sortFieldValue = sortDirection;

            string orderby = sortFieldValue + " " + sortOrderValue;
            int pageIndex = start / limit;
            int pageSize = limit;

            Guid orgTypeIdValue = Guid.Empty;
            try
            {
                orgTypeIdValue = new Guid(orgTypeId);
            }
            catch
            {
            }

            #endregion

            int recordCount;
            IEnumerable<OrganizationObject> organizations;
            if (Kit.IsEmpty(q))
            {
                LinqPredicate linqPredicate = new LinqPredicate("OrganizationType.Domain=@0 AND Status=@1", domain, OrganizationStatus.Enabled);
                if (orgTypeIdValue != Guid.Empty)
                    linqPredicate.Add("OrganizationTypeId=@0", orgTypeIdValue);

                organizations = organizationApi.FindOrganizations(linqPredicate, orderby, pageIndex, pageSize, out recordCount);
            }
            else
            {
                LinqPredicate linqPredicate = new LinqPredicate("OrganizationType.Domain=@0 AND Status=@1 AND (OrganizationCode.StartsWith(@2) || OrganizationName.Contains(@3))", domain, OrganizationStatus.Enabled, q, q);

                if (orgTypeIdValue != Guid.Empty)
                    linqPredicate.Add("OrganizationTypeId=@0", orgTypeIdValue);

                organizations = organizationApi.FindOrganizations(linqPredicate, orderby, pageIndex, pageSize, out recordCount);
            }

            return new OrganizationQueryResult(organizations.ToList()) { PageIndex = pageIndex, PageSize = pageSize, TotalRecordCount = recordCount };
        }
        /// <summary>
        /// Execute query for results binding to dynamic page grid.
        /// </summary>
        /// <param name="parameter">Query parameter.</param>
        /// <returns>Returns query results.</returns>
        public override QueryResults Query(QueryParameter parameter)
        {
            LinqPredicate predicate = LinqPredicate.Concat(parameter.Expressions.Compile(), this.CreateCustomQuery(parameter));

            int recordCount;
            string sortingExpression = null;
            if (parameter.SortExpression != null)
                sortingExpression = parameter.SortExpression.Compile();
            if (Kit.IsEmpty(sortingExpression))
                sortingExpression = "LastUpdatedDate ASC";

            string hierarchyType = authenticationContext.TempVariables["HierarchyType"] as string;
            LinqPredicate hierarchyTypePredicate = new LinqPredicate("HierarchyType=@0", hierarchyType);
            predicate = hierarchyTypePredicate.Add(predicate);

            IEnumerable<HierarchyDataObject> hierarchyDataObjects = hierarchyApi.FindHierarchyData(predicate, sortingExpression, parameter.PageIndex, parameter.PageSize, out recordCount);
            return new QueryResults(recordCount, hierarchyDataObjects);
        }
 public void MergeNullOrEmptyLinqPredicate()
 {
     LinqPredicate predicate = new LinqPredicate("City=@0 AND Height>=@1", "Shanghai", 170);
     predicate.Add((LinqPredicate)null);
     predicate.Add(new LinqPredicate(null));
     predicate.Add((string)null);
     Assert.AreEqual("(City=@0 AND Height>=@1)", predicate.Expression);
     Assert.AreEqual(2, predicate.Parameters.Length);
 }