【问题标题】:Get Item in all languages in which it has a version获取具有版本的所有语言的项目
【发布时间】:2014-04-07 14:43:57
【问题描述】:

假设我们有一个 Item Product(它有 en、jp、zh 和 ru 中的 0 个版本)。我怎样才能在 en、jp 和 zh 而不是 ru 中获得这个项目。

我尝试了下面的代码。

Item tempItem = Sitecore.Context.Database.GetItem(tempID);
foreach (var itemLanguage in tempItem.Languages)
{
  //Do Something
}

这里tempItem.Languages 正在返回所有四种语言,而我预计只有三种语言,因为 ru 没有版本。

这是实现这一目标的正确方法吗?

【问题讨论】:

    标签: sitecore sitecore7


    【解决方案1】:

    您需要检查返回项目的版本计数。可能有更好的方法来实现这一点,但是按照您自己的代码示例,它看起来像这样:

    Item tempItem = Sitecore.Context.Database.GetItem(tempID);
    foreach (var itemLanguage in tempItem.Languages)
    {
        var item = tempItem.Database.GetItem(tempItem.ID, itemLanguage);
        if (item.Versions.Count > 0)
        {
            // do something. If there is no "ru" version, this will be 0
        }
    }
    

    【讨论】:

      【解决方案2】:

      我进行了一项实验,以获取具有不同子项数量的项目的版本数量的语言列表,以检查这在系统上的成本。

      下面的脚本会返回一个列表,其中包含具有该项目版本的语言名称。

      public static List<string> LanguagesWithContent(this Item item)
      {
          var result = ItemManager.GetContentLanguages(item).Select(lang => new {
              lang.Name,
              Versions = ItemManager.GetVersions(item, lang).Count
              //this is better than db.GetItem(item.ID, lang).Versions.Count      
          }).Where(t => t.Versions > 0).Select(t => t.Name).ToList();
          return result;
      }
      

      基准性能

      使用 GetVersions 首次加载 - 当数据不是来自缓存时

      • 0.7298ms 获取 8 个语言版本的版本计数。加载项目的时间:9.3041 毫秒。语言:es-ES、es-MX、sv-SE、en、it-IT、pt-BR、fr-FR、de-DE
      • 0.0448ms 获得 7 种语言版本的版本计数。加载项目的时间:2.0039 毫秒。语言:es-ES、es-MX、en、it-IT、fr-FR、de-DE、ro-RO
      • 0.0334ms 获得 6 种语言版本的版本计数。加载项目的时间:3.145 毫秒。语言:es-ES、es-MX、en、it-IT、fr-FR、de-DE
      • 0.0307ms 获得 5 种语言版本的版本计数。加载项目的时间:1.5976ms。语言:es-MX、en、it-IT、fr-FR、de-DE
      • 0.0353ms 获得 4 种语言版本的版本计数。加载项目的时间:10.2764 毫秒。朗斯:en、de-DE、ja-JP、da
      • 0.0258ms 以获取具有 3 个语言版本的版本计数。加载项目的时间:1.9507ms。朗斯:en、de-DE、ja-JP
      • 0.0193 毫秒以获取具有 2 个语言版本的版本计数。加载项目的时间:2.0533ms。 Langs: en, de-DE
      • 0.0201ms 以获取具有 1 个语言版本的版本计数。加载项目的时间:4.7689 毫秒。朗斯:zh

      重复第一次加载实验,使用 GetItem 而不是 GetVersions

      结论:最好使用 ItemManager.GetVersions(item, lang).Count 比 db.GetItem(item.ID, lang).Versions.Count 获取项目包含的语言版本列表。

      • 3.4936ms 获得 8 种语言版本的版本计数。加载项目的时间:8.9118ms。语言:es-ES、es-MX、sv-SE、en、it-IT、pt-BR、fr-FR、de-DE
      • 0.9966ms 获得 7 个语言版本的版本计数。加载项目的时间:1.6489 毫秒。语言:es-ES、es-MX、en、it-IT、fr-FR、de-DE、ro-RO
      • 1.0875ms 获得 6 种语言版本的版本计数。加载项目的时间:3.1538 毫秒。语言:es-ES、es-MX、en、it-IT、fr-FR、de-DE
      • 0.5891ms 获得 5 种语言版本的版本计数。加载项目的时间:1.4402ms。语言:es-MX、en、it-IT、fr-FR、de-DE
      • 2.2096ms 获得 4 种语言版本的版本计数。加载项目的时间:9.8701ms。朗斯:en、de-DE、ja-JP、da
      • 0.9255ms 获取 3 种语言版本的版本计数。加载项目的时间:2.5175ms。朗斯:en、de-DE、ja-JP
      • 0.7606ms 以获取具有 2 个语言版本的版本计数。加载项目的时间:2.2407 毫秒。 Langs: en, de-DE
      • 1.9032 毫秒以获取 1 个语言版本的版本计数。加载项目的时间:5.0206ms。朗斯:zh

        后续加载 - 项目已缓存

        在这种情况下使用 ItemManager.GetVersions(item, lang)。 GetItem 理论上应该会给出类似的结果,因为后续加载会利用缓存。

      • 0.569ms 获得 8 种语言版本的版本计数。加载项目的时间:0.0372ms。语言:es -ES、es-MX、sv-SE、en、it-IT、pt-BR、fr-FR、de-DE
      • 0.0429ms 获得 7 种语言版本的版本计数。加载项目的时间:0.0475ms。语言:es-ES、es-MX、en、it-IT、fr-FR、de-DE、ro-RO
      • 0.025ms 获得 6 种语言版本的版本计数。加载项目的时间:0.0247ms。语言:es-ES、es-MX、en、it-IT、fr-FR、de-DE
      • 0.0239ms 以获取具有 5 个语言版本的版本计数。加载项目的时间:0.0201ms。语言:es-MX、en、it-IT、fr-FR、de-DE
      • 0.0342ms 获得 4 种语言版本的版本计数。加载项目的时间:0.0216ms。朗斯:en、de-DE、ja-JP、da
      • 0.0258ms 以获取具有 3 个语言版本的版本计数。加载项目的时间:0.0197ms。朗斯:en、de-DE、ja-JP
      • 0.0228 毫秒以获取具有 2 个语言版本的版本计数。加载项目的时间:0.019ms。 Langs: en, de-DE
      • 0.0228ms 以获取 1 个语言版本的版本计数。加载项目的时间:0.0178ms。朗斯:zh

      【讨论】:

      • 您的基准测试结果是 x 次运行的平均值吗?还是您每次测试只测量一次?您列出的数字看起来很奇怪。
      • 这是单次运行的快照,而不是平均值。虽然我确实多次运行它以检查数字是否一致。
      • 迭代 db.GetLanguages() 比迭代 item.GetLanguages() 更好。它们都返回您系统上使用的相同语言列表(在 /sitecore/system/languages 中),但 item.GetLanguages 慢得多。我每个都运行了 100 次迭代,db.GetLanguages() 用了 0.2 毫秒,而 item.GetLanguages() 用了 387.3 毫秒。不要遍历 Sitecore.Globalization.LanguageDefinitions.Definitions - 它会返回已知语言定义的完整列表(在我的例子中是 131 个)