При создании каждой развязочной таблицы генерируется класс записи развязочной таблицы. Его исходным описанием служит название развязочной таблицы (Name), а списком его свойств – соответствующие свойства развязочной таблицы .
Например, рассмотрим создание простой развязочной таблицы LinkTableName со свойствами ReferenceID, AnotherReferenceID и Value.
Класс модели предметной области, сгенерированный по этому описанию, выглядит следующим образом:
[Table(Name = "VLINKTABLENAME"), Serializable] [LocalizedDisplayName(typeof(LinkTableName), "Ultima.Metadata.Classes.Resources", "LinkTableName")] public partial class LinkTableName : ILinkTableRecord, IEntity, ISerializable, ICloneable, IRevertibleChangeTracking, IEditableObject, INotifyPropertyChanging, INotifyPropertyChanged, IEquatable<LinkTableName> { [Column(Name = "REFERENCE_ID", CanBeNull = false, IsPrimaryKey = true)] [Browsable(true)] [LocalizedDisplayName(typeof(LinkTableName), "Ultima.Metadata.Classes.Resources", "LinkTableName_ReferenceID")] public long ReferenceID { get; set; }
[Column(Name = "ANOTHER_REFERENCE_ID", CanBeNull = false, IsPrimaryKey = true)] [Browsable(true)] [LocalizedDisplayName(typeof(LinkTableName), "Ultima.Metadata.Classes.Resources", "LinkTableName_AnotherReferenceID")] public long AnotherReferenceID { get; set; }
[Column(Name = "VALUE", CanBeNull = false)] [Browsable(true)] [LocalizedDisplayName(typeof(LinkTableName), "Ultima.Metadata.Classes.Resources", "LinkTableName_Value")] public decimal Value { get; set; } } |
Все классы записей развязочных таблиц реализуют следующие интерфейсы:
•ILinkTableRecord – наследуется от базового интерфейса IEntity. Реализуется только классами записей развязочных таблиц, соответственно можно получить перечень всех классов записей развязочных таблиц, запросив кто реализует этот интерфейс;
public interface ILinkTableRecord : IEntity { } |
•IEntity – базовый для классов всех объектов интерфейс;
•ISerializable – обеспечивает поддержку эффективной сериализации (подробное описание интерфейса можно найти на сайте MSDN eng/rus);
•ICloneable – обеспечивает поддержку клонирования объекта (подробное описание интерфейса можно найти на сайте MSDN eng/rus);
•IRevertibleChangeTracking – обеспечивает поддержку отката изменений (подробное описание интерфейса можно найти на сайте MSDN eng/rus), реализует:
▪метод AcceptChanges – сбрасывает состояние объекта в неизмененное, принимая изменения;
▪метод RejectChanges – восстанавливает неизмененное состояние объекта, отменяя изменения;
▪свойство IsChanged – возвращает значение true, если содержание объекта было изменено с момента последнего вызова метода AcceptChanges, в противном случае – значение false;
•IEditableObject – предоставляет функциональные возможности транзакционного редактирования в стиле DataRowView (подробное описание интерфейса можно найти на сайте MSDN eng/rus), реализует методы:
▪BeginEdit – начинает редактирование объекта;
▪CancelEdit – уничтожает изменения, выполненные после последнего вызова метода BeginEdit;
▪EndEdit – подтверждает изменения, выполненные с момента последнего вызова метода BeginEdit;
•INotifyPropertyChanging – событие для поддержки привязки данных к элементам управления WinForms (подробное описание интерфейса можно найти на сайте MSDN eng/rus);
•INotifyPropertyChanged – событие для поддержки привязки данных к элементам управления WinForms (подробное описание интерфейса можно найти на сайте MSDN eng/rus);
•IEquatable<T> – обеспечивает возможность сравнения текущего объекта с указанным объектом того же типа.
Информация о метаданных развязочной таблицы хранится в статических полях ее же класса и описывается следующим образом:
public static IClassDescriptor StaticClassDescriptor { get { return new LinkTableDescriptor { ID = 3329, Name = "LinkTableName", Caption = ResourceHelper.GetString(typeof(LinkTableName).Assembly, "Ultima.Metadata.Classes.Resources", "LinkTableName"), Type = typeof(Price), ImplementedInterfaces = new List<string> { "ILinkTableRecord" }, TableName = "LINKTABLENAME", MapObjectName = "VLINKTABLENAME", Comments = string.Empty, FilterProperties = new List<string> {"ReferenceID", "AnotherReferenceID", "Value" }, DisplayFormat = string.Empty, IsKernel = false, IconName = null, LargeIconName = null, Icon = null, LargeIcon = null, Properties = new List<LinkTablePropertyDescriptor> { new LinkTablePropertyDescriptor { ID = 3332, Name = "ReferenceID", Caption = ResourceHelper.GetString( typeof(LinkTableName).Assembly, "Ultima.Metadata.Classes.Resources", "LinkTableName_ReferenceID"), Type = PropertyTypes.Long, ColumnName = "REFERENCE_ID", DefaultValue = "-1", Comments = string.Empty, StringSize = 0, IsRequired = true, IsPrimaryKey = true, }, new LinkTablePropertyDescriptor { ID = 3344, Name = "AnotherReferenceID", Caption = ResourceHelper.GetString( typeof(LinkTableName).Assembly, "Ultima.Metadata.Classes.Resources", "LinkTableName_AnotherReferenceID"), Type = PropertyTypes.Long, ColumnName = "ANOTHER_REFERENCE_ID", DefaultValue = "-1", Comments = string.Empty, StringSize = 0, IsRequired = true, IsPrimaryKey = true, }, new LinkTablePropertyDescriptor { ID = 3350, Name = "Value", Caption = ResourceHelper.GetString( typeof(LinkTableName).Assembly, "Ultima.Metadata.Classes.Resources", "LinkTableName_Value"), Type = PropertyTypes.Decimal, ColumnName = "VALUE", DefaultValue = string.Empty, Comments = string.Empty, StringSize = 0, IsRequired = true, IsPrimaryKey = false, }, }, References = new List<LinkTableReferenceDescriptor> { new LinkTableReferenceDescriptor { Name = "Reference", Caption = ResourceHelper.GetString( typeof(LinkTableName).Assembly, "Ultima.Metadata.Classes.Resources", "LinkTableName_Reference"), Type = "ReferenceDictionary", ThisKey = "ReferenceID", Comments = string.Empty, GetClassDescriptor = () => ReferenceDictionary.StaticClassDescriptor, }, new LinkTableReferenceDescriptor { Name = "AnotherReference", Caption = ResourceHelper.GetString( typeof(LinkTableName).Assembly, "Ultima.Metadata.Classes.Resources", "LinkTableName_AnotherReference"), Type = "AnotherReferenceDictionary", ThisKey = "AnotherReferenceID", Comments = string.Empty, GetClassDescriptor = () => AnotherReferenceDictionary.StaticClassDescriptor, }, }, }; } } |
Каждый генерируемый класс имеет статическое свойство StaticClassDescriptor типа IClassDescriptor. Обратившись к этому свойству, можно получить все свойства класса, на какие колонки они отображены и так далее. Дескрипторы подробно описаны в разделе Дескрипторы классов.
Каждому свойству записи развязочной таблицы соответствует поле типа EditableValue<T>, где Т – один из указанных в метаданных типов. Класс EditableValue<T> реализует следующие интерфейсы:
•ISerializable;
•ICloneable;
•IRevertibleChangeTracking;
•IEditableObject;
•IEquatable<T> – обеспечивает возможность сравнения текущего объекта с указанным объектом того же типа.