Драйвер MongoDB C # - сериализация ссылок POCO? - PullRequest
7 голосов
/ 02 июля 2011

Я сейчас исследую MongoDB . Насколько я понимаю, официальный драйвер C # может выполнять сериализацию и десериализацию POCOs . То, что я пока не нашел информацию о том, как ссылка между двумя объектами сериализуется. [Я говорю о чем-то, что будет представлено в виде двух отдельных документов со ссылками на идентификаторы, а не встраиваемыми документами.

Может ли механизм сериализации справиться с такой ситуацией? (1):

class Thing {
    Guid Id {get; set;}
    string Name {get; set;}
    Thing RelatedThing {get; set;}
}

Или мы должны пожертвовать некоторым ООП и сделать что-то подобное? (2):

class Thing {
    Guid Id {get; set;}
    string Name {get; set;}
    Guid RelatedThing_ID {get; set;}
}

UPDATE:

Просто пара связанных вопросов ...

a) Если сериализатор может справиться с ситуацией (1). Что является примером того, как сделать это без использования встраивания?

b) При использовании встраивания можно ли будет выполнять запросы по всем «вещам» независимо от того, были ли они «родителями» или встроенными элементами? Как будет выглядеть такой запрос?

Ответы [ 4 ]

12 голосов
/ 06 июля 2011

Драйвер C # может обрабатывать сериализацию класса, содержащего ссылку на другой экземпляр самого себя (1). Тем не менее:

  1. Как вы и предполагали, он будет использовать встраивание для представления этого
  2. В графе объектов не должно быть круговых путей, иначе произойдет переполнение стека

Если вы хотите сохранить его как отдельный документ, вам придется использовать второй класс (2) и выполнить несколько вставок.

Запросы на нескольких уровнях на самом деле невозможны, когда объект хранится как один большой документ с вложенным вложением. Возможно, вы захотите взглянуть на некоторые альтернативы, такие как:

http://www.mongodb.org/display/DOCS/Trees+in+MongoDB

0 голосов
/ 13 ноября 2013

Я недавно столкнулся с той же проблемой, и я обычно избегаю их, но ... я думаю, что это может быть полезным для существенной системы нумерации, развернутой в поле Id.

class Thing {
string Id {get; set;}
string Name {get; set;}
string RelatedThing {get; set;}}

Итак, упрощение, если Id был чем-то вроде "T00001" (или действительно T + GUID), вы могли бы легко получить набор вещей из Mongo, запрашивая что-то вроде Id, начинается с T и настраивая объекты для них всех (или только для подмножества, которое, как вы знаете, содержит вашу ссылку, если это очень большой набор).

Вы знаете / ожидаете, что RelatedThing будет Thing , но это будет просто строка, когда она вернется из Монго. Но если вы настроили объекты, как указано выше, вы можете эффективно использовать строку, как если бы она была ссылкой на объект (в конце концов, это то, чем она является на самом деле, сделано вроде «вручную»).

Это «свободный» способ сделать это, но может быть полезным для вас.

Может ли кто-нибудь увидеть какие-либо подводные камни при таком подходе?

0 голосов
/ 09 июля 2011

Если вы действительно хотите ссылку на другой документ, вы можете использовать DBRef . Однако в MongoDB есть ограничение на ссылки.

  • Вы можете запросить только по идентификатору на ссылку
  • когда вы получите документ Thing, вам нужно будет сделать второй запрос, чтобы получить связанный документ RelatingThing, поскольку в MongoDB нет объединения.
0 голосов
/ 02 июля 2011

Да, это вполне возможно.

Одна вещь, которую вы должны понимать о MongoDB и большинстве решений NoSQL, - это то, что объекты могут содержаться в других объектах. В случае MongoDB, в принципе, если вы можете создать объект в JSON, то вы можете создать объект в MongoDB.

В общем, вы должны стремиться иметь «относительно» денормализованную структуру базы данных. Немного дублированных данных - это нормально, если вы не часто их обновляете.

...