#c# #linq #lucene #sitecore #sitecore7
#c# #linq #lucene #sitecore #sitecore7
Вопрос:
Я работаю над переносом блога с WordPress на Sitecore 7.2 и написал скрипт на c # для создания элементов. Чтобы предотвратить дублирование элементов, я создал метод расширения, чтобы проверить, есть ли у нас уже элемент.
/// <summary>
/// Check if item with given name exists as child amp; if yes,return that item
/// </summary>
/// <returns></returns>
public static Item GetItemIfExists(this Item parentItem, string itemName)
{
Item childItem = null;
using (var context = Constants.Index.CreateSearchContext())
{
childItem = context.GetQueryable<SearchResultItem>().Where(i => i.Path.Contains(parentItem.Paths.FullPath) amp;amp; i.Name == itemName).Select(i => (Item)i.GetItem()).FirstOrDefault();
}
return childItem;
}
Этот метод использует функциональность поиска содержимого Sitecore, но выдает следующую ошибку:
Неправильный тип: System.Linq.IQueryable
1[[Sitecore.Data.Items.Item,
1[[Sitecore.Поиск содержимого.Типы поиска.SearchResultItem, Sitecore.ContentSearch, версия = 1.0.0.0, Культура = нейтральная, PublicKeyToken = null]]
Sitecore.Kernel, Version=7.0.0.0, Culture=neutral,
PublicKeyToken=null]]. Expected:
System.Linq.IQueryable
Хотя, если я изменю метод следующим образом, он работает нормально:
/// <summary>
/// Check if item with given name exists as child amp; if yes,return that item
/// </summary>
/// <returns></returns>
public static Item GetItemIfExists(this Item parentItem, string itemName)
{
var childItem = new List<Item>();
using (var context = Constants.Index.CreateSearchContext())
{
childItem = context.GetQueryable<SearchResultItem>().Where(i => i.Path.Contains(parentItem.Paths.FullPath) amp;amp; i.Name == itemName).Select(i => (Item)i.GetItem()).ToList();
}
return childItem.FirstOrDefault();
}
Каков наилучший способ вернуть один элемент из Sitecore content search?
Ответ №1:
Попробуйте использовать .Where(i => i.Path.Contains(parentItem.Paths.FullPath) amp;amp; i.Name == itemName).Take(1).ToList()
Помните, что запрос собирается до того, как он будет перечислен, поэтому, как только вы вызываете ToList или Select, запрос отправляется в индекс поиска и перечисляется, с этого момента вы не можете изменять запрос (поскольку он уже был отправлен), поэтому порядок ваших инструкций linq важен.
Вы можете видеть в примере, что мы вызываем Take()
(чтобы ограничить вызов) перед перечислением.
Вы также можете заглянуть в каталог search.log' in your
журналов, чтобы увидеть разницу между запросами.
Если вы использовали LINQPad раньше, я бы рекомендовал (соединитель LINQPad Адама Конна для Sitecore ContentSearch), это позволит вам поэкспериментировать с запросами linq по вашему собственному поисковому индексу.