使用Sitecore数据提供者

时间:2016-04-18 11:17:26

标签: sitecore sitecore8 dataprovider sitecore8.1

Hej Guys

我有一个相当大的问题,我的任务是创建一个自定义数据提供程序,用于从SOLR数据库中提取库存单位(SKU)到sitecore,而不实际用项目填充数据库。

我创建了一个数据提供程序,它成功地从SOLR数据库中提取数据a"创建" sitecore中的项目,使用以下代码:

public class SkuDataProvider : DataProvider, ISkuDataProvider
{
        private readonly string _targetDatabaseName = "master";
        private readonly string _idTablePrefix = "Skus";
        private readonly ID _skuTemplateId = new ID("{F806B403-BDAF-4C60-959D-E706A82FC1DC}");
        private readonly ID _skuRootTemplateId = new ID("{9767BC47-0A95-40E9-A2DE-3766FF241411}");

        private readonly IEnumerable<SkuItemInfo> _skus;

        public SkuDataProvider(/*IProductPageService productPageService*/)
        {
            _skus = new MockDataForSkuDataProvider().GetSimpleSkuCollection();
        }


        public override ItemDefinition GetItemDefinition(ID itemId, CallContext context)
        {
            Assert.ArgumentNotNull(itemId, "itemID");

            // Retrieve the sku id from Sitecore's IDTable
            var skuId = GetSkuIdFromIdTable(itemId);

            if (!string.IsNullOrEmpty(skuId))
            {
                // Retrieve the sku data from the skus collection
                var sku = _skus.FirstOrDefault(o => o.SkuId == skuId);

                if (sku != null)
                {
                    // Ensure the sku item name is valid for the Sitecore content tree
                    var itemName = ItemUtil.ProposeValidItemName($"{sku.SkuId}_{sku.Name}");

                    // Return a Sitecore item definition for the sku using the sku template
                    return new ItemDefinition(itemId, itemName, ID.Parse(_skuTemplateId), ID.Null);
                }
            }

            return null;
        }

        private string GetSkuIdFromIdTable(ID itemId)
        {
            var idTableEntries = IDTable.GetKeys(_idTablePrefix, itemId);

            if (idTableEntries.Any())
                return idTableEntries[0].Key.ToString();

            return null;
        }

        public override IDList GetChildIDs(ItemDefinition parentItem, CallContext context)
        {
            if (CanProcessParent(parentItem.ID))
            {
                var itemIdList = new IDList();

                foreach (var sku in _skus)
                {
                    var skuId = sku.SkuId;

                    // Retrieve the Sitecore item ID mapped to his sku
                    IDTableEntry mappedId = IDTable.GetID(_idTablePrefix, skuId) ??
                                            IDTable.GetNewID(_idTablePrefix, skuId, parentItem.ID);

                    itemIdList.Add(mappedId.ID);
                }

                context.DataManager.Database.Caches.DataCache.Clear();

                return itemIdList;
            }

            return base.GetChildIDs(parentItem, context);
        }


        private bool CanProcessParent(ID id)
        {
            var item = Factory.GetDatabase(_targetDatabaseName).Items[id];

            bool canProcess = item.Paths.IsContentItem && item.TemplateID == _skuRootTemplateId && item.ID == new ID("{F37753A0-BC79-4FF7-B975-A8F142AACD76}");

            return canProcess;
        }


        public override ID GetParentID(ItemDefinition itemDefinition, CallContext context)
        {
            var idTableEntries = IDTable.GetKeys(_idTablePrefix, itemDefinition.ID);

            if (idTableEntries.Any())
            {
                return idTableEntries.First().ParentID;
            }

            return base.GetParentID(itemDefinition, context);
        }


        public override FieldList GetItemFields(ItemDefinition itemDefinition, VersionUri version, CallContext context)
        {
            var fields = new FieldList();

            var idTableEntries = IDTable.GetKeys(_idTablePrefix, itemDefinition.ID);

            if (idTableEntries.Any())
            {
                if (context.DataManager.DataSource.ItemExists(itemDefinition.ID))
                {
                    ReflectionUtil.CallMethod(typeof(ItemCache), CacheManager.GetItemCache(context.DataManager.Database), "RemoveItem", true, true, new object[] { itemDefinition.ID });
                }

                var template = TemplateManager.GetTemplate(_skuTemplateId, Factory.GetDatabase(_targetDatabaseName));

                if (template != null)
                {
                    var skuId = GetSkuIdFromIdTable(itemDefinition.ID);

                    if (!string.IsNullOrEmpty(skuId))
                    {
                        var sku = _skus.FirstOrDefault(o => o.SkuId == skuId);

                        if (sku != null)
                        {
                            foreach (var field in GetDataFields(template))
                            {
                                fields.Add(field.ID, GetFieldValue(field, sku));
                            }
                        }
                    }
                }
            }

            return fields;
        }

        protected virtual IEnumerable<TemplateField> GetDataFields(Template template)
        {
            return template.GetFields().Where(ItemUtil.IsDataField);
        }

        private string GetFieldValue(TemplateField field, SkuItemInfo sku)
        {
            string fieldValue = string.Empty;

            switch (field.Name)
            {
                case "Name":
                    fieldValue = sku.Name;
                    break;
                case "SkuId":
                    fieldValue = sku.SkuId;
                    break;
                default:
                    break;
            }
            return fieldValue;
        }
    }
} 

访问Sitecore后端时会出现问题,其中所有项目都以层次结构方式显示在存储区项目下方。

我已检查Root项是否设置了一个存储桶,并且所使用的模板是可存储的。 此外,在后端手动插入时,项目正确插入到存储桶中。

有没有人对我有所了解,如何解决这个问题?

最诚挚的问候 尼古拉

1 个答案:

答案 0 :(得分:1)

您需要在模板项的标准值上设置Is Bucketable标志,而不是模板项本身。

此外,商品的方式是&#34; bucketed&#34;是在创建或保存项目时通过事件。然后,Sitecore会创建存储区文件夹以存储项目。在您拥有虚拟项目的情况下,您需要通过数据提供程序处理它们的路径。

如果您只是希望它们以与标准存储桶相同的方式隐藏,那么我建议您在SKU Root文件夹下创建一个存储桶文件夹,并将该项目用作所有SKU虚拟项目的父项目。这样桶存储文件夹将被sitecore隐藏,您将获得与标准存储桶相同的视图。

这是要使用的模板: Bucket Folder Template