Дизайн пользовательского поля с помощью C# и RavenDB

Я столкнулся с ключевым вопросом дизайна, связанным с тем, как прикрепить настраиваемые поля к объектам в моей системе. Сущности представлены в C# и сохраняются в RavenDB. Мы примерно следуем арендаторам Domain Driven Design, и наши сущности являются совокупными корнями.

[Примечание: я хотел бы избежать каких-либо дебатов по поводу уместности общей функции, такой как настраиваемые поля, в подходе DDD. Предположим, у нас есть законный пользователь, которому нужно прикрепить и отобразить произвольные данные к нашим объектам. Кроме того, я сделал свои примеры общими для иллюстрации проблем дизайна. :)]

Мой вопрос касается того, как лучше всего разместить определения полей и экземпляры значений полей.

Представьте себе домен, в котором у нас есть совокупные корни Книги и Автора. Мы хотим, чтобы пользователи могли прикреплять произвольные атрибуты данных к экземплярам книг и авторов. Итак, мы могли бы определить настраиваемое поле с помощью такого класса:

public enum CustomFieldType
{
    Text,
    Numeric,
    DateTime,
    SingleSelect,
    MultiSelect
}

public class CustomFieldDefinition
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public CustomFieldType Type { get; set; }
    public Collection<string> Options { get; set; } 
}

CustomFieldDefinition (CFD), прикрепленный к Book, может иметь такие значения, как:

  • Идентификатор: BookCustomField\1
  • Имя: ФуКод
  • Тип: текст
  • Описание: специальный идентификатор Foo Corp.
  • Тип: текст
  • Параметры: null

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

нижний предел:

хранить только идентификатор CFD и значение экземпляра

to

высокий конец:

сохранить весь CFD вместе со значением

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

Высокий конец плохой, потому что будет много дублирования. CFD может быть довольно тяжелым для CFD списка выбора, потому что определение содержит все доступные для выбора параметры.

Первый вопрос: Сколько должно храниться в документе для каждой Книги? Достаточно, чтобы отобразить Книгу (и мне пришлось бы вернуться к CFD, чтобы отобразить параметры и описание если я позволю пользователю редактировать значение CF)?

Второй вопрос: Должен ли я хранить всю коллекцию CFD для одного типа объекта в одном документе или хранить каждый CFD в отдельном документе? введите здесь описание изображения

Каждый CFD как документ упрощает работу с каждым CFD (особенно когда я начинаю делать такие вещи, как деактивация определений), но затем мне нужен способ отделить CFD книги от CFD автора. Это также заставляет меня загружать 1 документ для каждого CF, прикрепленного к объекту, всякий раз, когда я хочу редактировать объект.

Все CFD для данного типа в одном документе позволяют мне загрузить только один документ, но затем я также загружаю все деактивированные определения.

Третий вопрос... Есть ли лучший способ реализовать это в целом?

Четвертый вопрос... Есть ли какие-нибудь образцы или решения с открытым исходным кодом, чтобы мне не пришлось заново изобретать это колесо?


person Eric Farr    schedule 12.07.2013    source источник
comment
Изучили ли вы использование dynamic для пользовательских данных?   -  person Matt Johnson-Pint    schedule 13.07.2013
comment
Кроме того, все ли Book используют один и тот же набор настраиваемых полей? Как насчет вариантов этих полей, могут ли они быть разными для каждой книги?   -  person Matt Johnson-Pint    schedule 13.07.2013
comment
Мэтт, в любой момент времени в каждой книге используется один и тот же набор настраиваемых полей, но со временем этот набор может меняться. Таким образом, у Книги прошлого года могут быть другие поля, чем у Книги сегодняшнего дня.   -  person Eric Farr    schedule 13.07.2013
comment
Ничего страшного, если через год я посмотрю в книгу и увижу поля, которые существуют сегодня? Что, если у меня есть данные только из полей, которых больше нет? Или я должен просто увидеть поля и параметры в том виде, в каком они были в прошлом году, когда книга была добавлена ​​в систему?   -  person Matt Johnson-Pint    schedule 13.07.2013
comment
Я думаю, что книга годичной давности должна отображать настраиваемые поля по состоянию на год назад.   -  person Eric Farr    schedule 13.07.2013


Ответы (1)


Поскольку вы сказали в комментариях:

... Книга годичной давности должна показывать настраиваемые поля годичной давности.

Я вижу только два жизнеспособных варианта.

Опция 1

  • Определения настраиваемых полей существуют в их собственных документах.
  • Каждая книга содержит копию определений настраиваемых полей, которые применяются к этой книге, а также выбранные значения для каждого настраиваемого поля.
  • Они копируются при первом создании книги, но могут быть скопированы снова, если ваша логика сочтет это целесообразным. Возможно, при редактировании вы захотите создать новую копию, что потенциально сделает недействительными текущие выборки.
  • Преимущества: автономный, простой в индексировании и управлении.
  • Недостатки: множество копий определений настраиваемых полей. Требования к хранению могут быть очень большими.

Вариант 2

  • Используйте Temporal Versioning Bundle (отказ от ответственности: я являюсь его автором).
  • Определения настраиваемых полей все еще существуют в их собственных документах, но они отслеживаются во времени. Это означает, что изменения в настраиваемых полях будут сохраняться в пригодной для использования истории.
  • Книги содержат только выбранные значения. Они не содержат копий определений.
  • Книги не нужно отслеживать во времени, но им нужна какая-то дата вступления в силу в их данных. Возможно, дата «внесена». Используйте все, что имеет смысл для вас.
  • Отношение Book-to-CFD относится к типу Nt:Tx. Вы можете найти другой пример этого типа отношения здесь. Вы можете получить обзор временных отношений, чтобы сделать некоторые смысл этого. Осторожно, это сложная тема, и она быстро усложняется.
  • Преимущества: Требуется гораздо меньше места для хранения, так как существует не так много дублирующих копий данных определения настраиваемого поля.
  • Недостатки: кривая обучения. Сложность работы с темпоральными данными. Требование установить пользовательский пакет на сервере базы данных.

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

person Matt Johnson-Pint    schedule 14.07.2013