Должны ли мои классы документов Azure DocumentDB наследоваться от Microsoft.Azure.Documents.Document?

Я вижу какое-то странное поведение при сохранении в DocumentDB. Я начал сохранять документы, используя простой старый класс, который выглядел так:

public class Person
{
    public string Name;
    public int Age;
}

Я сохранил эти документы следующим образом:

var person = new Person { ... };
client.CreateDocumentAsync(myCollectionLink, person);

Это сработало нормально. Свойства были сохранены точно с именами в классе. Затем я понял, что мне нужен SelfLink документа, чтобы выполнять обновления и удаления. «Ах, — подумал я. "Я просто выведу из Document, вот так:

public class Person: Microsoft.Azure.Documents.Document
{
    public string Name;
    public int Age;
}

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

Я перепроверил несколько раз. Наследование от документа предотвращает сохранение моих пользовательских свойств в документе...

... если я явно не украсил каждый из них [JsonProperty], например:

public class Person: Document
{
    [JsonProperty(PropertyName="name")]
    public string Name;

    [JsonProperty(PropertyName="age")]
    public int Age;
}

Затем он снова работает (конечно, используя новые, более подходящие для JSON имена свойств camelCase). И после извлечения объекты заполняются свойством SelfLink, которое мне нужно для обновлений и удалений. Все хорошо.

На мои вопросы...Почему это произошло? Я делаю что-то не так, производя от Document? Мы будем очень признательны за ваши отзывы.


person Brian Rak    schedule 07.05.2015    source источник


Ответы (1)


Такое поведение связано с тем, как JSON.NET обрабатывает свойства динамических объектов. Он фактически игнорирует их, если вы не украсите их атрибутом JsonProperty.

Вы можете работать либо с простым POCO, либо с расширением Resource (показан ниже), который является статическим объектом, расширяемым самим Document.

public class Person: Microsoft.Azure.Documents.Resource
{
    public string Name;
    public int Age;
}
person Ryan CrawCour    schedule 07.05.2015
comment
Спасибо, Райан! Это действительно работает лучше. Один дополнительный вопрос — является ли какой-то конкретный подход (документ + атрибуты или ресурс) предпочтительным в качестве наилучшей практики? - person Brian Rak; 07.05.2015
comment
Полностью спас меня. Я не мог найти НИКАКОЙ документации, подобной этой, за всю мою жизнь. Спасибо - person Ryan Bennett; 26.08.2015
comment
Рад, что увидел это, я рвал на себе волосы целый час, пытаясь понять, почему наследование от Document не работает. - person James Alexander; 01.09.2015
comment
Есть ли какая-либо документация по использованию простых POCO, наследуемых от ресурсов или использующих динамические объекты и/или плюсы и т. д.? - person Mark Redman; 03.10.2017
comment
Мы дольше всего использовали POCO с DocDb и хотели начать использовать _ts и _etag, поэтому мы расширили документ (вероятно, из примера или ответа SO). Мы видели действительно неприятное поведение из-за динамической природы документа (например, повторяющиеся ключи в сериализованном JSON). Вот несколько документов, в которых говорится, что расширение ресурсов — неплохая идея: docs.microsoft.com/en-us/dotnet/api/ - person Jacob McKay; 30.03.2018
comment
Дублирующиеся ключи в сериализованном JSON привели меня к этому ответу, и нет, я также не нашел его нигде. Другой побочный эффект, который я отмечу здесь (для будущих искателей), заключается в том, что если вы выберете один документ по идентификатору и сериализуете его в POCO, наследуемый от Document, все будет хорошо. Но если вы возвращаете коллекцию, каждый отдельный элемент включает динамические атрибуты, которые вызывают дублирующую сериализацию. Если вы попытаетесь обновить один из них, обновленное значение не будет зафиксировано И это приведет к сбою индекса для него. Переключение базы на Resource решило все это. - person Brett; 04.11.2018