我想要创建一个通用的方法,允许我使用(.Net 4.5)搜索一个Sitecore 7索引。
这将用于各种搜索,例如:
我可以创建一个非常通用的搜索方法,它适用于所有类型的页面。它为Where子句提供了一个泛型模板谓词,适用于所有类型的搜索。
但是,对于上面的搜索,我还需要为Where子句添加特定谓词,为Order等添加特定表达式。目的是为每种类型的搜索创建子类,以实现这些细节。
我浓缩了一些代码,如下所示。在这篇文章中,我尝试为新的页面搜索添加特定功能。
所有的页面类都是从"Base“派生的。
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的行的注释,这也是一个类似的错误。
如何创建具有每种类型搜索的特定功能的泛型方法?
发布于 2015-01-29 03:09:07
按以下方式修改您的代码可以满足您的需要。
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);
}
我所做的改变是:
Expression<Func<T, bool>>
,但将其转换为object
,编译器会发出抱怨,首先解决这个问题。发布于 2013-11-21 23:54:17
我在附近找到了一份工作。
而不是:
Expression<Func<NewsPageBase, bool>> datePredicate = PredicateBuilder.False<NewsPageBase>();
datePredicate = datePredicate.And(newsPage => newsPage.ArticleDate < DateTime.Now);
您可以使用:
Expression<Func<T, bool>> innerPredicate = PredicateBuilder.False<T>();
innerPredicate = innerPredicate.Or(item => ((DateTime)item[(ObjectIndexerKey)"article_date"] < DateTime.Now));
对于OrderBy子句,可以使用:
searchQuery = searchQuery.OrderByDescending(item => item[(ObjectIndexerKey)"article_date"]);
如果你的基类是从SearchResultItem类中子类出来的,这就可以了。
https://stackoverflow.com/questions/20092603
复制