5.1 Модель данных, используемая в API
Модель данных строится на следующих понятиях:
Атрибут – обычно соответствует полю таблицы БД.
Атрибут может быть одного из следующих типов:
Строка: формат String
Целое число: формат Int64, в БД может иметь формат Int16, Int32.
Дата-время: формат DateTime в UTC, в БД может иметь формат локального времени.
Дробное (десятичное) число: формат Decimal
Перечисление: тип enum
Коллекция сущностей: IEnumerable<T>, где T - это тип интерфейса сущности
Ссылка на сущность: тип интерфейса сущности
Интерфейс сущности - описывает структуру таблицы в БД. Все интерфейсы сущностей наследуются от интерфейса IKeyedEntity. Интерфейсы для сущностей генерируются на основе метаданных hbm.xml. Генерация происходит в момент сборки приложения. Интерфейсы могут наследоваться друг от друга.
Класс сущности – соответствует строке таблицы БД. Все сущности наследуются от соответствующих генерируемых интерфейсов. Класс сущности может реализовывать основной и несколько дополнительных интерфейсов (расширение класса). Генерация сущностей происходит в момент старта приложения.
Коллекция сущностей – объединяет множество сущностей одного типа. В коде представлена как интерфейс IEnumerable от соответствующего интерфейса сущности. Соответствует набору строк таблицы.
Ссылка на сущность – представляет идентификатор сущности. В коде представлена, как интерфейс соответствующей сущности.
Классы модели данных системы «ДЕЛО» определены в сборке Eos.Delo.Platform.Storage.Module, пространство имен - Eos.Delo.Platform.Storage.Model.
Рассмотрим описанные понятия на примере некоторых сущностей системы.
Пример кода интерфейса сущности:
|
// Интерфейс сущности, соответствующей таблице DOC_RCpublic interface IDocRc : IKeyedEntity
{
Int64? IsnDoc
{
get;
set;
}
Int64 KindDoc
{
get;
set;
}
String DueDocgroup
{
get;
set;
}
DateTime DocDate
{
get;
set;
}
...
IEnumerable<IAcquaintance> Acquaintances
{
get;
set;
}
IEnumerable<IDocExe> DocExes
{
get;
set;
}
IEnumerable<IDocFolderItem> DocFolderItems
{
get;
set;
}
...
ISecurityCl SecurityCl
{
get;
set;
}
INomenklCl NomenklCl
{
get;
set;
}
IDocvidCl DocvidCl
{
get;
set;
}
IArRcValue ArRcValue
{
get;
set;
}
IQueryable<IRefLink> GetRefLinks(IDataContext context);
IQueryable<IRefFile> GetRefFiles(IDataContext context);
}
|
Интерфейс IDocRc является интерфейсом сущности, соответствующей таблице DOC_RC. Атрибутами этого объекта являются, например, свойства DueDocgroup и IsnDoc, которые соответствуют полям таблицы - DUE_DOCGROUP и ISN_DOC.
Поле Department типа IDepartment является ссылкой на сущность. Интерфейс IDepartment соответствует таблице DEPARTMENT. Поле Resolutions типа IEnumerable<IResolution> является коллекцией сущностей для интерфейса сущности.
Все интерфейсы сущностей унаследованы от базового интерфейса IKeyedEntity, который имеет полезное свойство-индексатор, позволяющее обращаться к элементам сущности по имени в случаях, когда конкретный тип или элементы типа не известны на момент разработки.
Пример кода описания базового интерфейса, от которого наследуются все сущности:
|
// Описание базового интерфейса, от которого наследуются все сущности
public interface IKeyedEntity
{
object[] KeyValues { get; }
[System.Runtime.CompilerServices.IndexerName("__Item")]
object this[string name] { get; set; }
...
}
|
В процессе разработки прикладного кода доступны только интерфейсы сущностей. Классы, реализующие интерфейсы и позволяющие работать с БД посредством ORM Entity Framework не доступны для непосредственного использования. Код классов генерируется динамически при старте приложения.
Пример динамической генерации кода классов:
|
// Динамическая генерация кода класса
[Display(Name="DocRc_name", Description="DocRc_description", ResourceType=typeof(Eos.Delo.Platform.Storage.Properties.Resources))]
public partial class DocRc : IDocRc
{
partial void Initialize();
private Int32? _IsnDoc;
private Int16 _KindDoc;
private String _DueDocgroup;
...
private ICollection<Acquaintance> _Acquaintances;
private ICollection<DocExe> _DocExes;
private ICollection<DocFolderItem> _DocFolderItems;
...
private SecurityCl _SecurityCl;
private NomenklCl _NomenklCl;
private DocvidCl _DocvidCl;
private ArRcValue _ArRcValue;
internal DocRc()
{
Initialize();
this._Acquaintances = new HashSet<Acquaintance>();
this._DocExes = new HashSet<DocExe>();
this._DocFolderItems = new HashSet<DocFolderItem>();
}
[NotMapped()]
public virtual object [] KeyValues
{
get
{
return new object [] { IsnDoc };
}
}
[Display(Name="DocRc_IsnDoc_name", Description="DocRc_IsnDoc_description", ResourceType=typeof(Eos.Delo.Platform.Storage.Properties.Resources))]
[Range(-2147483648, 2147483647, ErrorMessageResourceName="range", ErrorMessageResourceType=typeof(Eos.Delo.Platform.Storage.Properties.Resources))]
public virtual Int32? IsnDoc
{
get
{
return this._IsnDoc;
}
set
{
this._IsnDoc = value;
}
}
Int64? IDocRc.IsnDoc
{
get
{
return this.IsnDoc;
}
set
{
checked
{
this.IsnDoc = (Int32?)value;
}
}
}
[System.Runtime.CompilerServices.IndexerName("__Item")]
public virtual object this[string name]
{
get
{
if ((name == "IsnDoc"))
{
return this.IsnDoc;
}
}
|
В модели данных прикладной системы ряд интерфейсов сущностей наследуются от общего базового интерфейса.
Также некоторые сущности в системе имеют возможность расширения - т.е. добавление реквизитов, не включенных в стандартную модель системы. С помощью этого механизма реализованы дополнительные реквизиты РК, РКПД и некоторых справочников.
На пример кода класса сущности дополнительных реквизитов РКПД, видно, что класс реализует два интерфейса: IArPrjValue, IArPrjValueAdd. Первый является базовым, и входит в базовую модель, в то время как второй формируется динамически в процессе работы системы по мере добавления новых реквизитов через приложение Администрирования.
Пример кода класса сущности с дополнительными реквизитами:
|
// Класс сущности РКПД с дополнительными реквизитами: IArPrjValue - базовый, IArPrjValueAdd - формируется динамически
public partial class ArPrjValue : IArPrjValue, IArPrjValueAdd
{
partial void Initialize();
private String _EosItemNumber;
...
private String _MedoDocKind;
private Int32? _IsnPrj;
private PrjRc _PrjRc;
internal ArPrjValue()
{
Initialize();
}
[NotMapped()]
public virtual object [] KeyValues
{
get
{
return new object [] { IsnPrj };
}
}
[Display(Name="ArPrjValue_EosItemNumber_name", Description="ArPrjValue_EosItemNumber_description", ResourceType=typeof(Eos.Delo.Platform.Storage.Properties.Resources))]
[MaxLength(255, ErrorMessageResourceName="maxlength", ErrorMessageResourceType=typeof(Eos.Delo.Platform.Storage.Properties.Resources))]
public virtual String EosItemNumber
{
get
{
return this._EosItemNumber;
}
set
{
this._EosItemNumber = value;
}
}
}
|
Полный перечень определенных в API сущностей системы и их связей приведен в в Приложение Г, Приложение Д.
