private static IQueryable <TEntity> ApplySort <TEntity>(this IQueryable <TEntity> query, Sort sort)
        {
            if (!query.Any() || sort == null || sort.IsUnsorted())
            {
                return(query);
            }

            var sortExpressions = new SortExpressions <TEntity, object>();
            var propertyInfos   = typeof(TEntity).GetProperties(BindingFlags.Public | BindingFlags.Instance);

            var orders = sort.Orders;

            foreach (var order in orders)
            {
                if (order == null || order.Property == null)
                {
                    continue;
                }

                var isDescending = order.Direction.IsDescending();
                var propertyInfo = propertyInfos.FirstOrDefault(pi => pi.Name.Equals(order.Property, StringComparison.InvariantCultureIgnoreCase));
                if (propertyInfo == null)
                {
                    continue;
                }

                var expressionFunc = GetExpression <TEntity, object>(propertyInfo);
                sortExpressions.Add(expressionFunc, isDescending);
            }
            return(SortExpressions <TEntity, object> .ApplySorts(query, sortExpressions));
        }
        private void AddOrderByClause()
        {
            switch (OrderBy)
            {
            case OrderBy.Relevance:

                // Relevance ordering is done within the full text search
                // However, for empty search we also need to order by date

                if (StringUtils.IsBlank(GeneralKeyword))
                {
                    SortExpressions.RemoveAll(delegate(ISortExpression sortExpression)
                    {
                        string fieldName = sortExpression.FieldName.ToLower();

                        return(
                            fieldName == Asset.Columns.PublishDate.ToString().ToLower() ||
                            fieldName == Asset.Columns.AssetId.ToString().ToLower()
                            );
                    });

                    SortExpressions.Add(new DescendingSort(Asset.Columns.PublishDate));
                    SortExpressions.Add(new DescendingSort(Asset.Columns.AssetId));
                }

                break;

            case OrderBy.Popularity:

                // Order assets by download count.  If the download count is the same
                // favour newer assets, on the basis that they have achieved the same
                // download count in a shorter space of time.  This system breaks if
                // assets are published and unpublished, as the download count does not
                // reset when an asset is unpublished, so it will not be accurate.

                SortExpressions.Clear();
                SortExpressions.Add(new DescendingSort(Asset.Columns.DownloadCount));
                SortExpressions.Add(new DescendingSort(Asset.Columns.UploadDate));

                break;

            case OrderBy.Date:

                // Order by assets by date, with newer assets first

                SortExpressions.Clear();
                SortExpressions.Add(new DescendingSort(Asset.Columns.PublishDate));
                SortExpressions.Add(new DescendingSort(Asset.Columns.AssetId));

                break;
            }
        }