首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >带有特定where/order by子句的泛型Linq

带有特定where/order by子句的泛型Linq
EN

Stack Overflow用户
提问于 2013-11-20 09:56:05
回答 2查看 1.2K关注 0票数 3

我想要创建一个通用的方法,允许我使用(.Net 4.5)搜索一个Sitecore 7索引。

这将用于各种搜索,例如:

  • 获取前5位最新新闻页面
  • 获取最后20个事件页
  • 通用站点搜索
  • 等,等

我可以创建一个非常通用的搜索方法,它适用于所有类型的页面。它为Where子句提供了一个泛型模板谓词,适用于所有类型的搜索。

但是,对于上面的搜索,我还需要为Where子句添加特定谓词,为Order等添加特定表达式。目的是为每种类型的搜索创建子类,以实现这些细节。

我浓缩了一些代码,如下所示。在这篇文章中,我尝试为新的页面搜索添加特定功能。

所有的页面类都是从"Base“派生的。

代码语言:javascript
运行
复制
public virtual ReadOnlyCollection<T> Search<T>() where T : Base, new()
    {
        List<T> results = new List<T>();

        using (IProviderSearchContext context = ContentSearchManager.GetIndex("sitecore_web_index").CreateSearchContext())
        {
            Expression<Func<T, bool>> outerPredicate = PredicateBuilder.True<T>();

            // Create a predicate for the template id.
            Expression<Func<T, bool>> templatePredicate = PredicateBuilder.False<T>();
            templatePredicate = templatePredicate.Or(baseItem => (baseItem.TemplateIdFromIndex.Equals("8b1fc00c76314d32b8e1bce93dd41ccd")));

            // Create a predicate for a news page search.
            Expression<Func<NewsPageBase, bool>> datePredicate = PredicateBuilder.False<NewsPageBase>();
            datePredicate = datePredicate.And(newsPage => newsPage.ArticleDate < DateTime.Now);

            // 1. outerPredicate = outerPredicate.And(datePredicate);

            // 2. IQueryable<T> searchQuery = context.GetQueryable<T>().Where(outerPredicate).OrderByDescending(newsPage => newsPage.ArticleDate).Take(5);
            IQueryable<T> searchQuery = context.GetQueryable<T>().Where(outerPredicate);

            results = searchQuery.ToList();
        }

        return new ReadOnlyCollection<T>(results);
    }

此代码符合并运行。

但是,如果取消标记为1的行的注释,编译器就会从Anding带有特定新闻页谓词的泛型模板谓词中出错。

错误是“无法从使用中推断方法'Sitecore.ContentSearch.Linq.Utilities.PredicateBuilder.And(System.Linq.Expressions.Expression>,System.Linq.Expressions.Expression>的类型参数”。

如果取消标记为2的行的注释,这也是一个类似的错误。

如何创建具有每种类型搜索的特定功能的泛型方法?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-01-29 11:09:07

按以下方式修改您的代码可以满足您的需要。

代码语言:javascript
运行
复制
public virtual ReadOnlyCollection<T> Search<T>() where T : Base, new()
    {
        List<T> results = new List<T>();

        using (IProviderSearchContext context = ContentSearchManager.GetIndex("sitecore_web_index").CreateSearchContext())
        {
            Expression<Func<T, bool>> outerPredicate = PredicateBuilder.True<T>();

            // Create a predicate for a news page search.
            Expression<Func<NewsPageBase, bool>> datePredicate = PredicateBuilder.True<NewsPageBase>();
            datePredicate = datePredicate.And(newsPage => newsPage.ArticleDate < DateTime.Now);

            //outerPredicate = outerPredicate.And((Expression<Func<T,bool>>)(object)datePredicate);
            outerPredicate = outerPredicate.And((Expression<Func<T, bool>>)(object)datePredicate);

            // 2. IQueryable<T> searchQuery = context.GetQueryable<T>().Where(outerPredicate).OrderByDescending(newsPage => newsPage.ArticleDate).Take(5);
            IQueryable<T> searchQuery = context.GetQueryable<T>().Where(outerPredicate);

            results = searchQuery.ToList();
        }

        return new ReadOnlyCollection<T>(results);
    }

我所做的改变是:

  1. 删除未使用的templatePredicate --我不确定您是否打算使用它,或者在压缩原始代码时忘记删除它。
  2. 使用PredicateBuilder.True而不是PredicateBuilder.False创建PredicateBuilder.True--这是在.And()中使用的必要条件,否则不会返回任何结果。
  3. I(Un)方框datePredicate用于outerPredicate.And()。如果您尝试将datePredicate转换为Expression<Func<T, bool>>,但将其转换为object,编译器会发出抱怨,首先解决这个问题。
票数 2
EN

Stack Overflow用户

发布于 2013-11-22 07:54:17

我在附近找到了一份工作。

而不是:

代码语言:javascript
运行
复制
Expression<Func<NewsPageBase, bool>> datePredicate = PredicateBuilder.False<NewsPageBase>();
datePredicate = datePredicate.And(newsPage => newsPage.ArticleDate < DateTime.Now);

您可以使用:

代码语言:javascript
运行
复制
Expression<Func<T, bool>> innerPredicate = PredicateBuilder.False<T>();
innerPredicate = innerPredicate.Or(item => ((DateTime)item[(ObjectIndexerKey)"article_date"] < DateTime.Now));

对于OrderBy子句,可以使用:

代码语言:javascript
运行
复制
searchQuery = searchQuery.OrderByDescending(item => item[(ObjectIndexerKey)"article_date"]);

如果你的基类是从SearchResultItem类中子类出来的,这就可以了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20092603

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档