Home » Перенос свойств содержимого каталога — блог Куан Май

Перенос свойств содержимого каталога — блог Куан Май

Вчера коллега спросил меня, как нам перенести свойства содержимого каталога. К сожалению, официального способа сделать это нет. Однако есть несколько неофициальных способов сделать это. Сегодня мы рассмотрим способ, который я лично рекомендую – с точки зрения его безопасности и обратной совместимости.

Допустим, у нас есть FashionProduct с MSRP недвижимость с типом Moneyтеперь мы хотели бы изменить его на Decimal . Есть несколько хитрых способов сделать это, но все они требуют прямых манипуляций с базой данных, которых нам следует избегать – если это возможно.

Сначала нам понадобится этот фрагмент кода. он был «украдён» у моего коллеги и использовался бесчисленное количество раз. Вероятно, вы захотите добавить его в закладки, так как он, вероятно, пригодится в будущем (вероятно, мне следует сделать это самому, поскольку мне придется находить его каждый раз, когда мне понадобится). Это фрагмент для перемещения по структуре каталога в зависимости от желаемого типа контента.

public virtual IEnumerable GetEntriesRecursive(ContentReference parentLink, CultureInfo defaultCulture) where T : EntryContentBase
    {
        foreach (var nodeContent in LoadChildrenBatched(parentLink, defaultCulture))
        {
            foreach (var entry in GetEntriesRecursive(nodeContent.ContentLink, defaultCulture))
            {
                yield return entry;
            }
        }

        foreach (var entry in LoadChildrenBatched(parentLink, defaultCulture))
        {
            yield return entry;
        }
    }

    private IEnumerable LoadChildrenBatched(ContentReference parentLink, CultureInfo defaultCulture) where T : IContent
    {
        var start = 0;

        while (true)
        {
            var batch = _contentLoader.GetChildren(parentLink, defaultCulture, start, 50);
            if (!batch.Any())
            {
                yield break;
            }

            foreach (var content in batch)
            {
                // Don't include linked products to avoid including them multiple times when traversing the catalog
                if (!parentLink.CompareToIgnoreWorkID(content.ParentLink))
                {
                    continue;
                }

                yield return content;
            }
            start += 50;
        }
    }

Чтобы убедиться, что мы не загружаем много контента одновременно, размер пакета установлен 50, но это, конечно, можно настроить (на ваше усмотрение)!

Теперь самое интересное, где это действительно работает. Как только у нас будет контент, нам нужно будет перенести данные, это может быть просто, вот так

private void MigrateProperty(IEnumerable contents) where T: EntryContentBase
{
      var batch = new List();
      foreach(var content in contents)
      {
           var writeableClone = content.CreateWriteableClone();
           Transform(writeableClone);
           batch.Add(writeableClone);
      }
      _contentRepository.Publish(batch, PublishAction.SyncDraft);
}

С Transform вы можете делать со значением свойства все, что захотите. Поскольку вы можете просто переименовать его, он ничего не сможет сделать, кроме как присвоить значение новому свойству. Или в случае, о котором мы упоминали вначале, конвертируйте Money к Decimal это простая задача(Money это менее точная версия Decimal). Обратите внимание: если вы выполняете преобразование между типами данных, например из double к int существует потенциальная потеря данных, но вы, вероятно, уже об этом знаете.

Последний шаг — опубликовать изменение. Из соображений производительности это, вероятно, лучшее, что вы можете Publish метод расширения IContentRepository и сохраните несколько материалов в одном пакете — размером 50 или 100. При этом будут пропущены такие вещи, как создание новых версий, для оптимальной производительности. Вы можете прочитать об этом здесь Новый простой API пакетного сохранения для коммерции | Оптимизировать разработчик C

Остается вопрос, где его разместить. В идеальном мире я бы сказал, что на этапе миграции (т. е. класс, реализующий IMigrationStep ), поэтому вы гарантируете, что ваши данные будут правильно перенесены до того, как будет запущено что-либо еще, например ваш новый код, который обращается к новому свойству, или индексирование вашего контента после миграции. Но если у вас большой каталог, это займет время, и, возможно, не стоит позволять пользователям ждать его завершения. Для этого имеет смысл сделать это в запланированном задании, и когда оно завершится, вы переключитесь.

Миграция свойств — непростая и быстрая задача, но ее можно выполнить относительно легко. Это также напоминает нам о моделировании — постарайтесь сделать все правильно с самого начала, чтобы нам не пришлось мигрировать. В конце концов, самый быстрый код — это код, который не нужно запускать!

Read more:  - World Business Report, Акции производителя чипов Nvidia демонстрируют огромный рост на мировых рынках

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.