【问题标题】:How can I implement collections of objects in a Sitecore facet?如何在 Sitecore 方面实现对象集合?
【发布时间】:2016-11-18 11:50:15
【问题描述】:

This article 似乎暗示这是可能的,但似乎跳过了集合本身的关键实现。它列出了粗略的结构:

public interface ICoordinate : IElement
{
    float Longitude { get; set; }
    float Latitude { get; set; }
}

public interface IPlace : IElement
{
    string Description { get; set; }
    ICoordinate Coordinate { get; }
}

public interface IPlaces : IFacet
{
    IElementDictionary<IPlace> Places { get; }
}

正是我需要的对象集合。那么我该如何实现呢?

[Serializable]
  internal class Coordinate : Element, ICoordinate
  {
    private const string LONGITUDE = "Longitude";
    private const string LATITUDE = "Latitude";

    public float Longitude
    {
        get
        {
            return this.GetAttribute<float>( LONGITUDE );
        }
        set
        {
            this.SetAttribute( LONGITUDE, value );
        }
    }

    public float Latitude
    {
        get
        {
            return this.GetAttribute<float>( LATITUDE );
        }
        set
        {
            this.SetAttribute( LATITUDE, value );
        }
    }

    public Coordinate()
    {
      this.EnsureAttribute<float>(LONGITUDE);
      this.EnsureAttribute<float>(LATITUDE);
    }
  }

这是坐标,Places 呢?如何添加新地点?该文章似乎缺少此信息

【问题讨论】:

  • 如果同时回复,为什么还要加问题? :)
  • 帮助其他有同样问题的人! @SitecoreClimber It's perfectly valid (and encouraged) to do this。这就是为什么有一个“回答你自己的问题”复选框
  • xDB 官方文档目前缺乏。但是我已经写了许多冗长的博客如何实现这一点以及许多其他有助于的事情 - jonathanrobbins.co.uk/2015/12/08/…
  • 这实际上非常有用@JonathanRobbins。我在寻找答案时没有找到这些。
  • 哦,很多东西,sitecore facet,facet collection,collection null 等等。我在答案中添加了一个链接

标签: c# content-management-system sitecore


【解决方案1】:

在玩了很多之后,我设法把它拼凑起来。文章的关键部分(虽然没有很好解释)是:

用基注册属性、集合和字典 使用以下辅助方法在构造函数中创建类:

this.EnsureAttribute<TValue>( string name );
this.EnsureElement<TElement>( string name );
this.EnsureDictionary<TElement>( string name );
this.EnsureCollection<TElement>( string name );

所以集合"Ensured" 与属性不同。所以Places 类的实现(来自示例)看起来像:

[Serializable]
public Places : Facet, IPlaces
{
    private const string FIELD_PLACES = "Places";

    public Places()
    {
       this.EnsureDictionary<IPlace>(FIELD_PLACES);
    }


    public IElementDictionary<IPlace> Places 
    { 
      get
      {
          return this.GetCollection<IPlace>(FIELD_PLACES);
      }

    }
}

注意不同的 Get(this.GetCollection&lt;IPlace&gt;(FIELD_PLACES);) 和 Ensure 调用(this.EnsureDictionary&lt;IPlace&gt;(FIELD_PLACES);)。如果您不这样做,您的收藏将是nullIPlace.Coordinate 将以相同的方式设置。通过调用这些,它将为您实例化正确的集合。

添加也不简单(或解释)。 IElementDictionary 不公开 Add 方法。它确实暴露了Create()。使用反射工具快速查看一下,您可以看到它创建了一个项目并将其添加到字典中:

public TElement Create(string key)
{
    Assert.ArgumentNotNull(key, "key");
    TElement tElement = ModelFactory.CreateElement<TElement>();
    this.dictionary.Add(key, tElement);
    return tElement;
}

所以添加到 Places 字典中的内容类似于:

IPlaces places = _contact.GetFacet<IPlaces>("name form XML config");
IPlace newPlace = places.Places.Create();
newPlace.Description = "test";
ICoordinate newCoord = newPlace.Coordinate.Create();
newCoord.Longitude = 0;

无需保存等。持久化等由内部处理。

您需要注册所有 3 个“元素”,但只有最上面的切面 (IPlaces) 需要进入 XML 的 &lt;entities&gt; 集合。所以整个配置看起来像:

<sitecore>
    <model>
      <elements>
        <element interface="Namespace.IPlaces, Dllname" implementation="Namespace.Places, Dllname" />
        <element interface="Namespace.IPlace , Dllname" implementation="Namespace.Place, Dllname" />
        <element interface="Namespace.ICoordinate, Dllname" implementation="Namespace.Coordinate , Dllname" />

      </elements>
      <entities>
        <contact>
          <facets>
            <facet name="name form XML config" contract="Namespace.IPlaces, Dllname" />
          </facets>
        </contact>
      </entities>
    </model>
  </sitecore>

Subsequently I've seen this article 涵盖了这一点并详细介绍了自定义数据

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-18
    • 1970-01-01
    • 2017-01-09
    • 2012-05-21
    • 1970-01-01
    • 1970-01-01
    • 2018-02-03
    • 1970-01-01
    相关资源
    最近更新 更多