При создании каждой табличной части генерируется класс записи табличной части. Его исходным описанием служит название табличной части (Name) +"TablePartRow", а списком его свойств – соответствующие свойства табличной части.
Например, рассмотрим создание простой табличной части DocumentName со свойствами ArticleID и Amount.
Класс модели предметной области, сгенерированный по этому описанию, выглядит следующим образом:
[Table(Name = "VTP_DOCUMENTNAME"), Serializable] [LocalizedDisplayName(typeof(DocumentNameTablePartRow), "Ultima.Metadata.Classes.Resources", "DocumentNameTablePartRow")] public partial class DocumentNameTablePartRow : ITablePartRecord, IEntity, ISerializable, ICloneable, IRevertibleChangeTracking, IEditableObject, INotifyPropertyChanging, INotifyPropertyChanged, IEquatable<DocumentNameTablePartRow> { [Column(Name = "ARTICLE_ID", CanBeNull = false)] [Browsable(true)] [LocalizedDisplayName(typeof(DocumentNameTablePartRow), "Ultima.Metadata.Classes.Resources", "DocumentNameTablePartRow_ArticleID")] public long ArticleID { get; set; }
[Column(Name = "AMOUNT", CanBeNull = false)] [Browsable(true)] [LocalizedDisplayName(typeof(DocumentNameTablePartRow), "Ultima.Metadata.Classes.Resources", "DocumentNameTablePartRow_Amount")] public decimal Amount { get; set; }
[Column(Name = "ID", CanBeNull = false, IsPrimaryKey = true)] [Browsable(true)] [LocalizedDisplayName(typeof(DocumentNameTablePartRow), "Ultima.Metadata.Classes.Resources", "DocumentNameTablePartRow_ID")] public long ID { get; set; }
[Column(Name = "DOCUMENT_ID", CanBeNull = false)] [Browsable(true)] [LocalizedDisplayName(typeof(DocumentNameTablePartRow), "Ultima.Metadata.Classes.Resources", "DocumentNameTablePartRow_DocumentID")] public long DocumentID { get; set; }
[Column(Name = "TP_ENTRY_ID", CanBeNull = false)] [Browsable(true)] [LocalizedDisplayName(typeof(DocumentNameTablePartRow), "Ultima.Metadata.Classes.Resources", "DocumentNameTablePartRow_TablePartEntryID")] public long TablePartEntryID { get; set; }
[Column(Name = "CHECKED", CanBeNull = false)] [Browsable(true)] [LocalizedDisplayName(typeof(DocumentNameTablePartRow), "Ultima.Metadata.Classes.Resources", "DocumentNameTablePartRow_Checked")] public bool Checked { get; set; }
[Column(Name = "TRANSACTION_DATE", CanBeNull = false)] [Browsable(true)] [LocalizedDisplayName(typeof(DocumentNameTablePartRow), "Ultima.Metadata.Classes.Resources", "DocumentNameTablePartRow_TransactionDate")] public DateTime TransactionDate { get; set; }
[Column(Name = "DELETED", CanBeNull = false)] [Browsable(true)] [LocalizedDisplayName(typeof(DocumentNameTablePartRow), "Ultima.Metadata.Classes.Resources", "DocumentNameTablePartRow_Deleted")] public bool Deleted { get; set; }
[Column(Name = "DOCUMENT_DELETED", CanBeNull = false)] [Browsable(true)] [LocalizedDisplayName(typeof(DocumentNameTablePartRow), "Ultima.Metadata.Classes.Resources", "DocumentNameTablePartRow_DocumentDeleted")] public bool DocumentDeleted { get; set; } } |
Помимо свойств ArticleID и Amount сгенерированный класс содержит описания системных свойств, которые создаются автоматически для каждой табличной части.
Все классы записей развязочных таблиц реализуют следующие интерфейсы:
•ITablePartRecord – наследуется от базовых интерфейсов IEntity и IBusinessObject. Реализуется только классами записей табличных частей, соответственно можно получить перечень всех классов записей табличных частей, запросив кто реализует этот интерфейс;
public interface ITablePartRecord : IEntity, IBusinessObject { long DocumentID { get; set; } DateTime TransactionDate { get; set; } bool DocumentDeleted { get; set; } bool Deleted { get; set; } long TablePartEntryID { get; set; } bool Checked { get; set; } } |
•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 TablePartDescriptor { ID = 6784, Name = "DocumentNameTablePartRow", Caption = ResourceHelper.GetString( typeof(DocumentNameTablePartRow).Assembly, "Ultima.Metadata.Classes.Resources", "DocumentNameTablePartRow"), Type = typeof(DocumentNameTablePartRow), ImplementedInterfaces = new List<string> { "ITablePartRecord" }, TableName = "TP_DOCUMENT_NAME", MapObjectName = "VTP_DOCUMENT_NAME", Comments = string.Empty, Guid = new Guid("d4d13aae-e3f4-c7cc-3732-d2a70ca9db32"), DisplayFormat = "{TablePartEntryID}, {TransactionDate}, FilterProperties = new List<string> { "DocumentID", "TransactionDate", "Deleted", "DocumentDeleted" }, IconName = null, LargeIconName = null, Icon = null, LargeIcon = null, Properties = new List<TablePartPropertyDescriptor> { new TablePartPropertyDescriptor { ID = 6794, Name = "ArticleID", Caption = ResourceHelper.GetString( typeof(DocumentNameTablePartRow).Assembly, "Ultima.Metadata.Classes.Resources", "DocumentNameTablePartRow_ArticleID"), Type = PropertyTypes.Long, ColumnName = "ARTICLE_ID", DefaultValue = "-1", Comments = string.Empty, StringSize = 256, IsRequired = true, IsVisible = true, }, new TablePartPropertyDescriptor { ID = 6798, Name = "Amount", Caption = ResourceHelper.GetString( typeof(DocumentNameTablePartRow).Assembly, "Ultima.Metadata.Classes.Resources", "DocumentNameTablePartRow_Amount"), Type = PropertyTypes.Decimal, ColumnName = "AMOUNT", DefaultValue = string.Empty, Comments = string.Empty, StringSize = 256, IsRequired = true, IsVisible = true, }, new TablePartPropertyDescriptor { ID = 6785, Name = "ID", Caption = ResourceHelper.GetString( typeof(DocumentNameTablePartRow).Assembly, "Ultima.Metadata.Classes.Resources", "PurchaseArticleTablePartRow_ID"), Type = PropertyTypes.Long, ColumnName = "ID", DefaultValue = string.Empty, Comments = "Identity", StringSize = 256, IsRequired = true, IsVisible = false, }, new TablePartPropertyDescriptor { ID = 6786, Name = "DocumentID", Caption = ResourceHelper.GetString( typeof(DocumentNameTablePartRow).Assembly, "Ultima.Metadata.Classes.Resources", "DocumentNameTablePartRow_DocumentID"), Type = PropertyTypes.Long, ColumnName = "DOCUMENT_ID", DefaultValue = "-1", Comments = "Document identity", StringSize = 256, IsRequired = true, IsVisible = false, }, new TablePartPropertyDescriptor { ID = 6787, Name = "TablePartEntryID", Caption = ResourceHelper.GetString( typeof(DocumentNameTablePartRow).Assembly, "Ultima.Metadata.Classes.Resources", "DocumentNameTablePartRow_TablePartEntryID"), Type = PropertyTypes.Long, ColumnName = "TP_ENTRY_ID", DefaultValue = "-1", Comments = "Table part entry identity", StringSize = 256, IsRequired = true, IsVisible = false, }, new TablePartPropertyDescriptor { ID = 6788, Name = "Checked", Caption = ResourceHelper.GetString( typeof(DocumentNameTablePartRow).Assembly, "Ultima.Metadata.Classes.Resources", "DocumentNameTablePartRow_Checked"), Type = PropertyTypes.Boolean, ColumnName = "CHECKED", DefaultValue = "false", Comments = "Checked", StringSize = 256, IsRequired = true, IsVisible = false, }, new TablePartPropertyDescriptor { ID = 6789, Name = "TransactionDate", Caption = ResourceHelper.GetString( typeof(DocumentNameTablePartRow).Assembly, "Ultima.Metadata.Classes.Resources", "DocumentNameTablePartRow_TransactionDate"), Type = PropertyTypes.DateTime, ColumnName = "TRANSACTION_DATE", DefaultValue = string.Empty, Comments = "Document transaction date", StringSize = 256, IsRequired = true, IsVisible = false, }, new TablePartPropertyDescriptor { ID = 6790, Name = "Deleted", Caption = ResourceHelper.GetString( typeof(DocumentNameTablePartRow).Assembly, "Ultima.Metadata.Classes.Resources", "DocumentNameTablePartRow_Deleted"), Type = PropertyTypes.Boolean, ColumnName = "DELETED", DefaultValue = "false", Comments = "Deleted", StringSize = 256, IsRequired = true, IsVisible = false, }, new TablePartPropertyDescriptor { ID = 6791, Name = "DocumentDeleted", Caption = ResourceHelper.GetString( typeof(DocumentNameTablePartRow).Assembly, "Ultima.Metadata.Classes.Resources", "DocumentNameTablePartRow_DocumentDeleted"), Type = PropertyTypes.Boolean, ColumnName = "DOCUMENT_DELETED", DefaultValue = "false", Comments = "Document deleted", StringSize = 256, IsRequired = true, IsVisible = false, }, }, References = new List<TablePartReferenceDescriptor> { new TablePartReferenceDescriptor { Name = "Article", Caption = ResourceHelper.GetString( typeof(DocumentNameTablePartRow).Assembly, "Ultima.Metadata.Classes.Resources", "DocumentNameTablePartRow_Article"), Type = "Article", ThisKey = "ArticleID", Comments = string.Empty, GetClassDescriptor = () => Article.StaticClassDescriptor, }, new TablePartReferenceDescriptor { Name = "TablePartEntry", Caption = ResourceHelper.GetString( typeof(DocumentNameTablePartRow).Assembly, "Ultima.Metadata.Classes.Resources", "DocumentNameTablePartRow_TablePartEntry"), Type = "DocumentTablePart", ThisKey = "TablePartEntryID", Comments = "Table part entry", GetClassDescriptor = () => DocumentTablePart.StaticClassDescriptor, }, new TablePartReferenceDescriptor { Name = "Document", Caption = ResourceHelper.GetString( typeof(DocumentNameTablePartRow).Assembly, "Ultima.Metadata.Classes.Resources", "DocumentNameTablePartRow_Document"), Type = "Document", ThisKey = "DocumentID", Comments = "Document", GetClassDescriptor = () => Document.StaticClassDescriptor, }, }, }; } } |
Каждый генерируемый класс имеет статическое свойство StaticClassDescriptor типа IClassDescriptor. Обратившись к этому свойству, можно получить все свойства класса, на какие колонки они отображены и так далее. Дескрипторы подробно описаны в разделе Дескрипторы классов.
Каждому свойству записи табличной части соответствует поле типа EditableValue<T>, где Т – один из указанных в метаданных типов. Класс EditableValue<T> реализует следующие интерфейсы:
•ISerializable;
•ICloneable;
•IRevertibleChangeTracking;
•IEditableObject;
•IEquatable<T> – обеспечивает возможность сравнения текущего объекта с указанным объектом того же типа.