当我有一个Sitecore ID数组时,例如MultilistField中的TargetIDs,如何查询ContentSearchManager以返回所有SearchResultItem对象?
我尝试了以下内容,它提供了“仅支持常量参数”。错误。
using (var s = Sitecore.ContentSearch.ContentSearchManager.GetIndex("sitecore_master_index").CreateSearchContext())
{
rpt.DataSource = s.GetQueryable<SearchResultItem>().Where(x => f.TargetIDs.Contains(x.ItemId));
rpt.DataBind();
}
我想我可以使用多个OR查询手动构建Linq查询。有没有办法可以使用Sitecore.ContentSearch.Utilities.LinqHelper
为我构建查询?
假设我使用这种技术,是否值得将其用于10项?我刚刚开始我的第一个Sitecore 7项目,我记得我想尽可能多地使用索引。
最后,页面编辑器是否支持使用SearchResultItem作为源以某种方式编辑字段?
更新1 我编写了这个函数,它使用谓词构建器,正如dunston建议的那样。我还不知道这是否真的值得使用(而不是物品)。
public static List<T> GetSearchResultItemsByIDs<T>(ID[] ids, bool mustHaveUrl = true)
where T : Sitecore.ContentSearch.SearchTypes.SearchResultItem, new()
{
Assert.IsNotNull(ids, "ids");
if (!ids.Any())
{
return new List<T>();
}
using (var s = Sitecore.ContentSearch.ContentSearchManager.GetIndex("sitecore_master_index").CreateSearchContext())
{
var predicate = PredicateBuilder.True<T>();
predicate = ids.Aggregate(predicate, (current, id) => current.Or(p => p.ItemId == id));
var results = s.GetQueryable<T>().Where(predicate).ToDictionary(x => x.ItemId);
var query = from id in ids
let item = results.ContainsKey(id) ? results[id] : null
where item != null && (!mustHaveUrl || item.Url != null)
select item;
return query.ToList();
}
}
它强制结果与ID数组中提供的顺序相同,在我的情况下这很重要。 (如果有人知道更好的方法,那就很想知道)。
默认情况下,它还可确保项目具有URL。
我的主要代码变为:
var f = (Sitecore.Data.Fields.MultilistField) rootItem.Fields["Main navigation links"];
rpt.DataSource = ContentSearchHelper.GetSearchResultItemsByIDs<SearchResultItem>(f.TargetIDs);
rpt.DataBind();
我仍然好奇页面编辑器如何应对SearchResultItem或POCO(我的第二个问题),现在我将继续研究。
感谢阅读, 史蒂夫
答案 0 :(得分:3)
您需要使用谓词构建器来创建多个OR查询或AND查询。
以下代码应该有效。
using (var s = Sitecore.ContentSearch.ContentSearchManager.GetIndex("sitecore_master_index").CreateSearchContext())
{
var predicate = PredicateBuilder.True<SearchResultItem>();
foreach (var targetId in f.Targetids)
{
var tempTargetId = targetId;
predicate = predicate.Or(x => x.ItemId == tempTargetId)
}
rpt.DataSource = s.GetQueryable<SearchResultItem>().Where(predicate);
rpt.DataBind();
}