Как сериализовать пользовательскую коллекцию в MongoDB.Bson?

Документация для MongoDB.Bson.Serialization кажется тонкой. Я не могу понять, как правильно вставить мою пользовательскую коллекцию в документ MongoDB. Я использую их драйвер c# по умолчанию.

Это класс, который я пытаюсь сериализовать, но когда я смотрю на результат после его сериализации, а затем десериализации, коллекция пуста. Точнее, он создает новый экземпляр класса, но коллекция «_items» выходит нулевой. Я нашел это необычным, учитывая, что это была частная коллекция предметов интерьера. Эта коллекция является свойством гораздо большего класса, другие свойства класса сериализуются правильно. Я сериализовал это в XML, используя встроенные сериализаторы, и это сработало нормально. Я полагаю, что это, вероятно, что-то простое, но, если не считать создания пользовательской реализации сериализации, я не знаю, что это такое. Есть ли что-то, что я должен сделать, чтобы сериализатор рассматривал это как коллекцию?

Поскольку я новичок в MongoDB, я не понял, как выгружать большие необработанные документы, чтобы проверить, как выглядит сам документ MongoDB. Это то, над чем я сейчас работаю.

[XmlRootAttribute(ElementName = "Children", IsNullable = true)] 
public class ChildList : IList<SurveyItem>, ICollection<SurveyItem> 
{
    private SurveyItem _parent = null;
    public ChildList(SurveyItem iParent)
    {
        _parent = iParent;      
    }

    private List<SurveyItem> items = new List<SurveyItem>();        

    #region ICollection<SurveyItem> Members
    public void Add(SurveyItem item)
    {
        //wire up the child.
        item.Parent = _parent;
        items.Add(item);
    }

    public void Clear()
    {
        items.Clear();
    }

    public bool Contains(SurveyItem item)
    {
        return items.Contains(item);
    }

    public void CopyTo(SurveyItem[] array, int arrayIndex)
    {
        items.CopyTo(array, arrayIndex);
    }

    public int Count
    {
        get { return items.Count; }
    }

    public bool IsReadOnly
    {
        get { return false; }
    }

    public bool Remove(SurveyItem item)
    {
        item.Parent = null;
        return items.Remove(item);
    }
    #endregion

    #region IEnumerable<SurveyItem> Members
    public IEnumerator<SurveyItem> GetEnumerator()
    {
        return items.GetEnumerator();
    }
    #endregion

    #region IEnumerable Members
    IEnumerator IEnumerable.GetEnumerator()
    {
        return (items as IEnumerable).GetEnumerator();
    }
    #endregion

    #region IList<SurveyItem> Members
    public int IndexOf(SurveyItem item)
    {
        return items.IndexOf(item);
    }

    public void Insert(int index, SurveyItem item)
    {
        item.Parent = _parent;
        items.Insert(index, item);
    }

    public void RemoveAt(int index)
    {
        items[index].Parent = null;
        items.RemoveAt(index);
    }

    public SurveyItem this[int index]
    {
        get
        {
            return items[index];
        }
        set
        {
            value.Parent = _parent;
            items[index] = value;
        }
    }
    #endregion

    public SurveyItem[] ToArray()
    {
        SurveyItem[] output = new SurveyItem[items.Count];
        for (int i = 0; i < items.Count; i++)
        {
            output[i] = items[i];
        }
        return output;
    }
}

person ExCodeCowboy    schedule 24.06.2011    source источник
comment
Не могли бы вы рассказать подробности о гораздо большем классе? Вы можете сделать дамп необработанных документов с помощью команды mongodump. Вот как использовать его с одной коллекцией и запросом: >mongodb.org/display/DOCS/   -  person Martin Owen    schedule 28.06.2011


Ответы (1)


Сериализатор в драйвере C# просто ищет и сериализует общедоступные свойства чтения/записи класса. Сериализатор также имеет специальные случаи для стандартных классов коллекций в .NET, таких как Dictionary.

Элементы вашей коллекции хранятся в частном поле, называемом элементами. Вот почему они не сериализуются.

Вы можете написать собственный сериализатор для своего класса. Вы можете либо реализовать IBsonSerializable, либо написать IBsonSerializer и зарегистрировать его с помощью BsonSerializer.RegisterSerializer.

Одной из проблем, с которой вы, вероятно, столкнетесь, являются циклические ссылки: ваша коллекция имеет ссылку на родителя, который, скорее всего, в свою очередь имеет ссылку на дочерний элемент. Циклические ссылки трудно сериализовать.

person Robert Stam    schedule 09.07.2011