Ошибка при использовании Sitecore Content Search с Lucene при возврате одного элемента

#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,
Sitecore.Kernel, Version=7.0.0.0, Culture=neutral,
PublicKeyToken=null]]. Expected:
System.Linq.IQueryable
1[[Sitecore.Поиск содержимого.Типы поиска.SearchResultItem, Sitecore.ContentSearch, версия = 1.0.0.0, Культура = нейтральная, PublicKeyToken = null]]

Хотя, если я изменю метод следующим образом, он работает нормально:

             /// <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 по вашему собственному поисковому индексу.