1

按照Northwind DataProvider实现自定义读写提供程序。问题是当向内容树插入一个新项目时,它显示了该项目的两个副本,另一个基本上是“图像”,即相同的 ID 并且无法编辑,甚至无法单击该“图像”项目。但是对真实项目的任何更改都会显示在“图像”项目上(编辑、删除)。我还检查了外部数据库(SQL Server)表,只创建了一条记录。因此,奥秘在于 Sitecore 如何在内容树下两次显示该项目。

抱歉,我没有足够的声誉来发布截图。

方法代码:

  public override ItemDefinition GetItemDefinition(ID id, CallContext context)
  {
     ItemDefinition newItem = null;
     if (CanProcessChild(id, context))
     {
        object orifinalID = GetOriginalRecordID(id);

        StringBuilder sqlSelect = new StringBuilder();
        sqlSelect.AppendFormat("SELECT {0} FROM {1}", nameField, table);
        sqlSelect.Append(GetConditions(orifinalID));

        string[] result = SqlUtil.GetStringArray(sqlSelect.ToString(), connectionString);
        if (result.Length > 0)
        {
           string itemName = result[0];
           if (string.IsNullOrEmpty(itemName))
           {
              itemName = "unnamed item";
           }

           newItem = new ItemDefinition(id, itemName, MainDB.Templates[new ID(templateID)].ID, ID.Null);
           ((ICacheable)newItem).Cacheable = false;
        }
     }
     return newItem;
  }


  public override FieldList GetItemFields(ItemDefinition item, VersionUri version, CallContext context)
  {
     if (CanProcessChild(item.ID, context))
     {
        if (context.DataManager.DataSource.ItemExists(item.ID))
        {
           ReflectionUtil.CallMethod(
              typeof(ItemCache), CacheManager.GetItemCache(context.DataManager.Database),
              "RemoveItem", true, true, new object[] { item.ID });
        }

        CoreItem.Builder builder = CreateItemBuilder(item, context.DataManager);
        return builder.ItemData.Fields;
     }
     return null;

  public override bool CreateItem(ID itemID, string itemName, ID tempID, ItemDefinition parent, CallContext context)
  {
      if (new ID(templateID) == tempID && new ID(parentItemID) == parent.ID)
      {
          string fields = GetFieldsName();
          StringCollection valuesBuilder = new StringCollection();
          foreach (string field in fieldNames)
          {
              if (field == nameField)
              {
                  valuesBuilder.Add(String.Format("'{0}'", itemName));
                  continue;
              };
              if (field == idField)
              {
                  valuesBuilder.Add(String.Format("'{0}'", ID.Encode(itemID).Substring(0, 4)));
                  continue;
              };
              valuesBuilder.Add("''");
          }
          string values = StringUtil.StringCollectionToString(valuesBuilder, " ,");
          Insert(fields, values);
          IDTable.Add(ToString(), ID.Encode(itemID).Substring(0, 4), itemID, parent.ID);              
          context.Abort();
          return true;
      }
      return false;
  }

  CoreItem.Builder CreateItemBuilder(ItemDefinition item, DataManager dataManager)
  {
     CoreItem.Builder result = new CoreItem.Builder(item.ID, item.Name, item.TemplateID, dataManager);
     StringBuilder sqlSelect = new StringBuilder();
     sqlSelect.AppendFormat("SELECT {0} FROM {1}", fieldsNames, table);
     sqlSelect.Append(GetConditions(GetOriginalRecordID(item.ID)));
     using (SqlDataReader sqlResult = ExecuteReader(sqlSelect.ToString(), connectionString))
     {
        if (sqlResult.Read())
        {
           for (int i = 0; i < sqlResult.FieldCount; i++)
           {
              result.AddField(sqlResult.GetName(i), ToSitecoreValue(sqlResult.GetValue(i)));
           }
        }
     }
     return result;
  }

基本上 CreateItem 方法是直接插入到 SQL 表中,Sitecore 将拾取新插入的项目。我发现如果通过 sitecore 插入,在 Descendants 表中创建了一行;但是如果从外部数据库表创建,它不会创建这样的行,并且数据将正确显示而没有“图像”。

我是 sitecore 的新手,无法弄清楚这个问题的原因是什么。

非常感谢您的帮助!

4

1 回答 1

1

看起来多个提供商同时用于您的内容树。

如果要确保在数据提供程序运行后不运行任何后续数据提供程序,请调用传递给数据提供程序Abort()的对象上的方法。CallContext

Sitecore 社区文档中有关数据提供者的更多信息。

http://sitecore-community.github.io/docs/documentation/Sitecore%20Fundamentals/Data%20Providers/Implementing%20a%20Data%20Provider/API/

于 2015-05-27T15:13:32.673 回答