Хранение/извлечение динамических данных в RavenDB

Я использую RavenDB и вам нужно хранить динамические данные, например:

public class User {
    public string Name;
    public dynamic Data;
}

Похоже, что я мог бы использовать множество разных типов, таких как dynamic, RavenJObject, DynamicJsonObject, ExpandoObject, Dictionary<string, object>, но я не знаю, каковы различия.

Может ли кто-нибудь объяснить параметры динамических данных? Я не забочусь о запросах и больше о простом хранении и поиске.

Ответ 1

Проблема

Здесь сделка, если у вас есть свойство dynamic, тогда RavenDB будет всегда десериализовать его как RavenJObject. Например:

public class User {
    public dynamic Data = new ExpandoObject();
}

...

var user = new User();
user.Data.SomethingNew1 = "foo";

Это выглядит безобидно и прекрасно работает при создании вашего пользователя. Но когда вы Загрузить пользователь, RavenDB не знает, какой тип вы хотите для dynamic, поэтому он использует RavenJObject. Вы не можете динамически создавать свойства (expando style) с помощью RavenJObject, чтобы это не удалось:

var user = session.Find<User>(...);
user.Data.SomethingNew2 = "foo"; //compiles, but throws

Мое решение

Используйте ExpandoObject и явно определите его тип в сериализованном свойстве. Это позволяет RavenDB (или JSON, я думаю) знать, какого типа вы ожидаете, и ему не нужно угадывать RavenJObject. Затем, чтобы сохранить синтаксическую магию, оберните свойство динамическим аксессуаром.

public class User {
    public ExpandoObject _Data = new ExpandoObject();

    public dynamic Data {
        get { return _Data; }
    }
}

Есть способы сделать объект expando частным и создать сеттер для Data, но вы получите эту идею.

Дополнительные проблемы

Обновление: К сожалению, это решение предоставляет больше проблем. Скажем, вы сохраняете список строк в динамических данных:

user.Data.Keys = new List<String>{"a","b","c"};

После сериализации/десериализации JSON/Raven снова не знает, какого типа вы ожидаете. Поэтому, если вы попробуете это (см. Ниже), тогда он компилируется, но вы получаете исключение во время выполнения. Невозможно неявно преобразовать тип "Raven.Abstractions.Linq.DynamicList" в "System.Collections.Generic.List":

List<string> keys = user.Data.Keys;

Ответ 2

Для всех это не имеет значения, каков ваш тип памяти.

Объект

динамический и DynamicJsonObject - это то же самое, что касается RavenDB. Это дает вам динамическая реализация с использованием RavenJObject в качестве основы для этого.

RavenJObject - это буквально только то значение, которое вы получаете с сервера.

ExpandoObject и словарь сериализуются в/из словаря, все.