2

我正在尝试为投影模块创建一个自定义排序标准,以根据评级或收藏夹数量对任何内容进行排序。我已将 Orchard.Module.Contrib.Stars 模块中的 StarsPart 和 Orchard.Module.NGM.Favorite 模块中的 FavoritePart 附加到我的内容中。但是这些模块是基于 contrib.Voting 模块的,这些部分没有对应的 ContentPartRecord。

我的问题是如何编写 HQL 查询来对内容进行排序,如果我编写如下查询,那么我会收到“无法将类型对象转换为类型”的Orchard.ContentManagement.DefaultAliasFactory异常StarsPart

 if (context.State.SortBy != null)
        {
            var _SortBy = _tokenizer.Replace(context.State.SortBy, null, new ReplaceOptions { Encoding = ReplaceOptions.NoEncode });
            if (!string.IsNullOrWhiteSpace(_SortBy))
            {
                switch ((string)_SortBy)
                {
                    case "HighestRated":
                        context.Query.OrderBy(
                            alias => alias.ContentItem().As<StarsPart>(), x => x.Asc("UserRating"));
                        break;
                    case "MostFavorited":
                        context.Query.OrderBy(
                            alias => alias.ContentItem().As<FavoritePart>(), x => x.Asc("NumberOfFavorites"));
                        break;
                    default:
                         context.Query.OrderBy(
                            alias => alias.ContentItem().As<UserViewPart>(), x => x.Asc("TotalViews"));
                        break;
                }
            }
        }

还有其他方法可以编写此查询吗?

4

1 回答 1

0

我终于可以在这个 [问题] 的帮助下自己找出答案:Join Non ContentPart Table to ContentPart Table Using Orchard HQL API

这是 ApplyFilter 方法的最终代码。


 public void ApplyFilter(SortCriterionContext context)
    {

        bool ascending = false;
        if (context.State.SortAsc != null)
        {
            var _SortAsc = _tokenizer.Replace(
                context.State.SortAsc, null, new ReplaceOptions { Encoding = ReplaceOptions.NoEncode });
            if (!string.IsNullOrWhiteSpace(_SortAsc)) ascending = Convert.ToBoolean(_SortAsc);
        }

        System.Collections.IDictionary dictionary = new Dictionary<string, string>();

        if (context.State.SortBy != null)
        {
            var _SortBy = _tokenizer.Replace(
                context.State.SortBy, null, new ReplaceOptions { Encoding = ReplaceOptions.NoEncode });
            if (!string.IsNullOrWhiteSpace(_SortBy))
            {

                switch ((string)_SortBy)
                {
                    case "HR": //Highest Rated
                        dictionary.Add("Dimension", Dimensions.Rating.ToString());
                        dictionary.Add("FunctionName", "average");
                        break;
                    case "MF": //Most favorited
                        dictionary.Add("Dimension", Dimensions.Favorite.ToString());
                        dictionary.Add("FunctionName", "sum");
                        break;
                    case "MV":
                        //"Most viewed"
                        dictionary.Add("Dimension", Dimensions.ContentViews.ToString());
                        dictionary.Add("FunctionName", "sum");
                        break;
                        //ToDo: Need to work on recently published
                    default:
                        break;
                }
            }
        }

        if (dictionary.Keys.Count == 0)
        {
            //This is to handle default case. highest rating
            dictionary.Add("Dimension", Dimensions.Rating.ToString());
            dictionary.Add("FunctionName", "average");
        }
        {
            var query = (IHqlQuery)context.Query;
            query.Join(alias => alias.ContentItem());
            var defaultHqlQuery = query as DefaultHqlQuery;
            var fiJoins = typeof(DefaultHqlQuery).GetField("_joins", BindingFlags.Instance | BindingFlags.NonPublic);
            var joins = fiJoins.GetValue(defaultHqlQuery) as List<System.Tuple<IAlias, Join>>;
            joins.Add(
                new System.Tuple<IAlias, Join>(
                    new Alias("Contrib.Voting.Models"), new Join("ResultRecord", "result", ",")));

            context.Query = query.Where(
                alias => alias.Named("result"), predicate => predicate.EqProperty("ContentItemRecord", "ci"));
            context.Query = context.Query.Where(
                alias => alias.Named("result"), predicate => predicate.AllEq(dictionary));
            Action<IHqlSortFactory> sortOrderAction = x => x.Desc("Value");

            if (ascending) sortOrderAction = x => x.Asc("Value");

            context.Query = context.Query.OrderBy(alias => alias.Named("result"), sortOrderAction);
        }

    }
于 2013-06-11T14:20:41.260 回答