Особенности мастеровых ассоциаций и их свойства, пример генерации
Согласно базовой статье мастеровыми являются композиции, подобные:
Note: Принято, чтобы конец ассоциации имел множественность
*
, а начало 1
, либо ‘0..1` (иначе: проводите ассоциацию от мастерового класса ко внутреннему). Мастеровой класс всегда должен находиться со стороны начала ассоциации, а внутренний - со стороны конца. Note: При редактировании ассоциации на диаграмме классов нужно учитывать существующие особенности.
При этом генерируется ассоциация.
Генерация в SQL DDL. Определение структуры SQL DDL создаётся так:
- В таблице, соотв. внутреннему классу, - ссылка на таблицу, соотв. мастеровому классу;
- Constraint, связывающий таблицы.
Генерация в .Net-язык. Во внутреннем классе, - приватный член типа мастера и публичное виртуальное свойство с соответствующим модификатором (# - protected, + - public, - - private), поименованное, как имя роли, находящейся со стороны мастера. См. также Структура классов объектов данных.
Дополнительно редактируемые свойства и что как генерируется
Cвойства мастеровой ассоциации:
Свойство-Описание | Генерация в SQL DDL | Генерация в .Net-язык |
---|---|---|
Description - описание |
Никак | Описание в DocComment к свойству внутреннего класса, если оставлено пустым, DocComment не генерируется. |
StartRole - имя роли со стороны начала (со стороны мастера) |
Имя поля в таблице внутреннего класса, являющегося внешним ключом на таблицу мастерового класса, если другое имя не указано свойством Storage | Имя свойства и приватного члена внутреннего класса |
StartMultiplicity - мощность ассоциации со стороны начала (со стороны мастера) |
Если мощность 1, - в DDL скрипт CREATE TABLE для таблицы, соотв. внутреннему классу, в определении поля указывается NOT NULL. Если мощность 0..1 - NULL | Если мощность 1, - перед свойством во внутреннем классе генерируется указание атрибута NotNullAttribute (Namespace: ICSSoft.STORMNET, Assembly: ICSSoft.STORMNET.DataObject (in ICSSoft.STORMNET.DataObject.dll)) |
StartRoleAccessModifier - модификатор со стороны начала (со стороны мастера) |
Никак | Соответствующий модификатор свойства (# - protected, + - public, - - private) |
StartRoleStored |
Поле внешнего ключа в таблице, соотв. внутреннему классу, не генерируется. | Перед определением свойства указывается .Net-атрибут NotStoredAttribute (Namespace: ICSSoft.STORMNET, Assembly: ICSSoft.STORMNET.DataObject (in ICSSoft.STORMNET.DataObject.dll)) |
EndRole - имя роли со стороны конца, дублирует на диаграмме |
Никак | Не используется (зарезервировано) |
EndMultiplicity - мощность ассоциации со стороны начала, дублирует на |
Никак | Не используется (зарезервировано) |
AutoGenerateTypeUsage - автоматическая генерация используемых типов. |
В DDL-определении таблицы для внутреннего класса генерируются внешние ключи на каждый найденный класс. При этом поля именуются следующим образом: @@ |
Мастеровому свойству внутреннего класса прописывается .NET-атрибут TypeUsageAttribute, с указанием всех найденных классов. |
Storage - имя хранения |
Если указано, то такое и будет имя поля - внешнего ключа, а не StartRole. | Перед определением свойства генерируется указание атрибута PropertyStorageAttribute (Namespace: ICSSoft.STORMNET, Assembly: ICSSoft.STORMNET.DataObject (in ICSSoft.STORMNET.DataObject.dll)) |
TypeUsage - явное задание используемых типов. Не учитывается при установленном флаге AutoGenerateTypeUsage. Можно указать имена используемых типов (имена мастерового класса и любых его наследников, для которых должна быть актуальна данная мастеровая ассоциация), через запятую. |
В DDL-определении таблицы для внутреннего класса генерируются внешние ключи на каждый из указанных классов. При этом поля именуются следующим образом: @@ |
Мастеровому свойству внутреннего класса прописывается .NET-атрибут TypeUsageAttribute, с указанием указанных классов. |
AutoStoreMasterDisabled - отключение автоматического сохранения мастерового объекта при сохранении основного объекта. |
Никак | Перед определением мастерового свойства генерируется указание атрибута AutoStoreMasterDisabled (Namespace: ICSSoft.STORMNET, Assembly: ICSSoft.STORMNET.DataObject (in ICSSoft.STORMNET.DataObject.dll)) |
PBMasterCustomAttributes |
Никак | Если галочка указана - генерируется скобка программиста для “ручного” внесения .Net атрибутов перед кодом свойства. |
PBMasterGetEnd |
Никак | Если галочка указана - генерируется скобка программиста для “ручного” внесения кода перед концом аксессора get. |
PBMasterGetStart |
Никак | Если галочка указана - генерируется скобка программиста для “ручного” внесения кода после начала аксессора get. |
PBMasterSetEnd |
Никак | Если галочка указана - генерируется скобка программиста для “ручного” внесения кода перед концом аксессора set. |
PBMasterSetStart |
Никак | Если галочка указана - генерируется скобка программиста для “ручного” внесения кода после начала аксессора set. |
Автоматическая генерация работает следующим образом:
- Выполняется поиск всех наследников мастерового класса (в пределах стадии);
- Найденные классы, вместе с мастеровым классом, сортируются по названию по возрастанию;
- Результат является определением используемых типов.
Пример
Для вышепоказанной диаграммы код на C# выглядит так:
private ICSSoft.BugLeR.Пользователь fРегистратор;
// ........
// *** Start programmer edit section *** (Ошибка.Регистратор CustomAttributes)
// *** End programmer edit section *** (Ошибка.Регистратор CustomAttributes)
[NotNull())
public virtual ICSSoft.BugLeR.Пользователь Регистратор
{
get
{
// *** Start programmer edit section *** (Ошибка.Регистратор Get start)
// *** End programmer edit section *** (Ошибка.Регистратор Get start)
ICSSoft.BugLeR.Пользователь result = this.fРегистратор;
// *** Start programmer edit section *** (Ошибка.Регистратор Get end)
// *** End programmer edit section *** (Ошибка.Регистратор Get end)
return result;
}
set
{
// *** Start programmer edit section *** (Ошибка.Регистратор Set start)
// *** End programmer edit section *** (Ошибка.Регистратор Set start)
this.fРегистратор = value;
// *** Start programmer edit section *** (Ошибка.Регистратор Set end)
// *** End programmer edit section *** (Ошибка.Регистратор Set end)
}
}