Создание динамического пользовательского интерфейса ASP.NET, управляемого данными - Моделирование с динамическими атрибутами клиентов, специфичными для каждого пользователя
ОГЛАВЛЕНИЕ
Моделирование с динамическими атрибутами клиентов, специфичными для каждого пользователя
Каждому пользователю разрешено указать специализированные динамические атрбуты для своих клиентов. При определении таких атрибутов пользователь должен предоставить название атрибута и его тип. Динамически созданный атрибут может быть следующих типов:
- String
- Boolean
- Numeric
- Date
Список типов данных не содержит одной ключевой опции – поисковой таблицы, которая разрешит пользователю выбирать из списка опций (к примеру, выбирать единственную опцию из выпадающего списка, или множество опций из ListBox). Мы расширим возможности и включим больше типов данных в четвертой части серии статей.
Нам необходима таблица базы данных для того, чтобы смоделировать данные, доступные опции типов данных. Создайте новую таблицу, названную DynamicAttributeDataType, согласно следующей структуре:
Column Name | Data Type | Описание |
---|---|---|
DataTypeId | int | Первичный ключ |
DataTypeName | nvarchar(50) |
Обратите внимание на то, что колонка с первичным ключом, DataTypeId, является типа int, но не является колонкой IDENTITY. Это потому, что нам необходим контроль над значениями DataTypeId, связанными с каждым типом данных .
Далее добавьте следующие записи к этой таблице:
DataTypeId | DataTypeName |
---|---|
1 | String |
2 | Boolean |
3 | Numeric |
4 | Date |
В дополнение к указанию названия и типа данных, нам также может понадобиться разрешить пользователям предоставлять информацию о валидации - например, если поле является обязательным или если численное значение должно быть в определенных пределах. Мы рассмотрим данные возможности во второй и четвертой частях серии.
Теперь нам необходима таблица, которая имеет записи для каждого динамического атрибута пользователя. Создайте таблицу с названием DynamicAttributesForClients согласно следующей схеме:
Column Name | Data Type | Описание |
---|---|---|
DynamicAttributeId | uniqueidentifier | Первичный ключ; default value of NEWID() |
CustomerId | uniqueidentifier | Внешний ключ к Customers.CustomerId |
DataTypeId | int | Внешний ключ к DynamicAttributeDataTypes.DataTypeId |
AttributeName | nvarchar(50) | Название динамического атрибута |
SortOrder | int | Используется для того, чтобы указывать порядок хранения атрибутов, которые будут отображены в пользовательском интерфейсе |
Теперь у нас есть таблица (DynamicAttributesForClients) , которая хранит набор динамических атрибутов для клиентов каждого пользователя. Все что нам осталось, так это создать таблицу, которая хранит данные динамические значения для определенного клиента. Создайте таблицу с названием DynamicValuesForClients:
Column Name | Data Type | Описание |
---|---|---|
DynamicValueId | uniqueidentifier | Первичный ключ; default value of NEWID() |
ClientId | uniqueidentifier | Внешний ключ к Clients.ClientId |
AttributeId | uniqueidentifier | Внешний ключ к DynamicAttributesForClients.DynamicAttributeId |
DynamicValue | sql_variant | Значение для указанного динамического атрибута указанного клиента |
Обратите внимание на то, что колонока DynamicValue является типа sql_variant. Тип sql_variant позволяет колонкам хранить любой тип данных, отличающийся от text, ntext, nvarchar(max) и других типов данных типа BLOB. (Для получения более подробной информации читайте статьи про тип данных sql_variant).
Следующая ER-диаграмма демонстрирует таблицы, вовлеченные в хранение динамических атрибутов и их значений.
![](/images/stories/dotnet/aspnet-datadriven-ui/2.gif
)
При создании внешнего ключа между колонками DynamicAttributesForClients.DynamicAttributeId и DynamicValuesForClients.AttributeId вам понадобиться определиться с использованием каскадного удаления. Задайтесь вопросом, что должно произойти, когда пользователь (из юридической компании) удалит один из специализированных атрибутов. Хотите ли вы, чтобы значения клиентов были автоматически удалены? Если да, то настройте внешний ключ таким образом, чтобы он поддерживал каскадное удаление. Если значения должны быть сохранены, то тогда вам необходимо разрешить пользователю "отменить" специализированный клиентский атрибут. Отмена атрибуты сохранит его в базе данных (а также связанные с ним значения), но спрячет его от динамического пользовательского интерфейса, управляемого данными.
Аналогично в случае, когда клиент удаляется из таблицы Clients, то вам наверняка необходимо будет удалить специализированные значения из таблицы DynamicValuesForClients. Существует внешний ключ между Clients.ClientId и DynamicValuesForClients.ClientId, хотя в упомянутой выше диаграмме мы не указали это. Данный ключ поддерживает каскадное удаление, тем самым при удалении клиента, его специализированные значения будут автоматически удалены.
Усовершенствование модели данных |
---|
Конечно же, вполне возможно, что пользователю не надо будет сохранять конкретный специализированный клиентский атрибут. В таких случаях вы можете позволить пользователю полностью удалить его. Предполагая то, что ваш внешний ключ поддерживает каскадное удаление, можно быть уверенным что все значения будут автоматически удалены. Но что, если пользователь захочет сохранить те значения? В данном случае необходима возможность отметить их как отмененные (discontinued), что сохранит их в базе данных, но спрячет в динамическом пользовательском интерфейсе, управляемом данными. Чтобы предоставить данный уровень гибкости, добавьте колонку Discontinued к таблице DynamicAttributesForClients. Текущая модель данных, указанная выше (и доступная в конце данной статьи), не включает в себя данную колонку (Discontinued). Тем самым пользователь должен удалить атрибут и все связанные с ним значения в случае,если ему он больше не нужен. |