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项是否设置了一个存储桶,并且所使用的模板是可存储的。 此外,在后端手动插入时,项目正确插入到存储桶中。
有没有人对我有所了解,如何解决这个问题?
最诚挚的问候 尼古拉