logo

[ELMA3] Сущности

Сущность (тип сущности) – класс, экземпляры которого могут храниться в базе данных. Сущностям соответствует объект метаданных с типом EleWise.ELMA.Model.Metadata.EntityMetadata.

Каждый тип сущности имеет:

  • общие параметры: Имя (Имя класса), Отображаемое имя, Описание, Имя таблицы в базе данных и др. (см. класс EntityMetadata);
  • список свойств, каждое из которых имеет имя (имя свойства), отображаемое имя, описание, тип, настройки (ограничения, имя поля в таблице БД) и др. (см. класс EntityPropertyMetadata).

Дополнительно может иметь:

  • Фильтр – параметры, по которым может производиться поиск экземпляров сущностей (см. класс EntityFilterMetadata);
  • Действия – список действий с сущностью (см. класс EntityActionsMetadata).

Описание сущностей производится с помощью Редактора сущностей. При объявлении типов используются базовые интерфейсы для сущностей - EleWise.ELMA.Model.Entities.IEntity и EleWise.ELMA.Model.Entities.IEntity<TId>

namespace EleWise.ELMA.Model.Entities
{

    /// <summary>
    /// Базовый интерфейс сущности
    /// </summary>
    public interface IEntity
    {
        ///<summary>
        /// Возвращает строковое представление сущности
        ///</summary>
        ///<param name="format">Формат отображения, свойства доступны через {$Имя свойства}</param>
        ///<returns>Строка представляющая сущность</returns>
        string ToString(string format);

        /// <summary>
        /// Получить нетипизированное значение идентификатора у сущности
        /// </summary>
        /// <returns>Значение идентификатора</returns>
        object GetId();

        /// <summary>
        /// Получить значение свойства по его уникальному идентификатору
        /// </summary>
        /// <param name="propertyUid">Уникальный идентификатор свойства</param>
        /// <returns>Значение свойства</returns>
        object GetPropertyValue(Guid propertyUid);

        /// <summary>
        /// Получить значение свойства по его уникальному идентификатору
        /// </summary>
        /// <typeparam name="T">Тип свойства</typeparam>
        /// <param name="propertyUid">Уникальный идентификатор свойства</param>
        /// <returns>Значение свойства</returns>
        T GetPropertyValue<T>(Guid propertyUid);

        /// <summary>
        /// Установить значение свойства по его уникальному идентификатору
        /// </summary>
        /// <param name="propertyUid">Уникальный идентификатор свойства</param>
        /// <param name="value">Значение свойства</param>
        void SetPropertyValue(Guid propertyUid, object value);

        /// <summary>
        /// Сохранить сущность
        /// </summary>
        void Save();

        /// <summary>
        /// Удалить сущность
        /// </summary>
        void Delete();

        /// <summary>
        /// Обновить сущность из БД
        /// </summary>
        void Refresh();
    }

    /// <summary>
    /// Интерфейс сущности с идентификатором
    /// </summary>
    /// <typeparam name="IdT">Тип идентификатора (первичного ключа)</typeparam>
    public interface IEntity<IdT> : IEntity
    {

        /// <summary>
        /// Идентификатор (первичный ключ)
        /// </summary>
        IdT Id { get; set; }

    }

}

а также базовый класс для сущностей:

namespace EleWise.ELMA.Model.Entities
{

    /// <summary>
    /// Сущность с идентификатором
    /// </summary>
    /// <typeparam name="IdT">Тип идентификатора (первичного ключа)</typeparam>
    public abstract class Entity<IdT> : IEntity<IdT>
    {

        /// <summary>
        /// Идентификатор (первичный ключ)
        /// </summary>
        public virtual IdT Id { get; set; }

        /// <summary>
        /// Сохранить сущность
        /// </summary>
        public virtual void Save();

        /// <summary>
        /// Удалить сущность
        /// </summary>
        public virtual void Delete();

        /// <summary>
        /// Обновить сущность из БД
        /// </summary>
        public virtual void Refresh();

        /// <summary>
        /// Получить нетипизированное значение идентификатора у сущности
        /// </summary>
        /// <returns>Значение идентификатора</returns>
        public virtual object GetId();

        /// <summary>
        /// Получить значение свойства по его уникальному идентификатору
        /// </summary>
        /// <param name="propertyUid">Уникальный идентификатор свойства</param>
        /// <returns>Значение свойства</returns>
        public virtual object GetPropertyValue(Guid propertyUid);

        /// <summary>
        /// Получить значение свойства по его уникальному идентификатору
        /// </summary>
        /// <typeparam name="T">Тип свойства</typeparam>
        /// <param name="propertyUid">Уникальный идентификатор свойства</param>
        /// <returns>Значение свойства</returns>
        public virtual T GetPropertyValue<T>(Guid propertyUid);

        /// <summary>
        /// Установить значение свойства по его уникальному идентификатору
        /// </summary>
        /// <param name="propertyUid">Уникальный идентификатор свойства</param>
        /// <param name="value">Значение свойства</param>
        public virtual void SetPropertyValue(Guid propertyUid, object value);

        ///<summary>
        /// Возвращает строковое представление объекта в указанном формате
        ///</summary>
        ///<param name="format">Формат отображения, свойства доступны через {$Имя свойства}</param>
        ///<returns>Строка представляющая сущность</returns>
        public virtual string ToString(string format);

    }
   
}

Типы сущностей

В системе ELMA можно выделить несколько типов описания сущности в зависимости от их расширяемости.

Обычная сущность (Entity)

Обычная сущность – нерасширяемая сущность. Внешние модули не могут расширять/изменять ее. Данному типу сущности соответствует объект метаданных EleWise.ELMA.Model.Metadata.EntityMetadata со значением свойства Type равным EntityMetadataType.Entity.

Использовать данный тип сущности рекомендуется только в том случае, если Вы не хотите, чтобы другие модули могли расширять данную сущность!

На основе метаданных генерируется класс. Пример автогенерируемого кода:

    /// <summary>
    /// Пользователь
    /// </summary>
    [MetadataType(typeof(EntityMetadata))]
    [EntityMetadataType(EntityMetadataType.Entity)]
    public partial class User : Entity<long>
    {
        
        /// <summary>
        /// Учетная запись
        /// </summary>
        public string UserName { get; set; }
        
        /// <summary>
        /// Пароль
        /// </summary>
        public string Password { get; set; }

    }     

Интерфейс сущности (Entity Interface)

Интерфейс сущности – интерфейс, описывающий расширяемую сущность. Внешние модули могут расширять/изменять ее при помощи интерфейсов расширения. Данному типу сущности соответствует объект метаданных EleWise.ELMA.Model.Metadata.EntityMetadata со значением свойства Type равным EntityMetadataType.Interface.

На основе метаданных генерируется интерфейс. Пример автогенерируемого кода:

    /// <summary>
    /// Пользователь
    /// </summary>
    [MetadataType(typeof(EntityMetadata))]
    [EntityMetadataType(EntityMetadataType.Interface)]
    [Uid("04d5bcbf-4288-4d95-9745-1ebd0d690bb3")]
    [ImplementationUid("18faf3ae-03c9-4e64-b02a-95dd63e54c4d")]
    public partial interface IUser : IEntity<long>
    {
        
        /// <summary>
        /// Учетная запись
        /// </summary>
        string UserName { get; set; }
        
        /// <summary>
        /// Пароль
        /// </summary>
        string Password { get; set; }

    }   

Интерфейс расширения сущности (Entity Interface Extension)

Интерфейс расширения сущности – интерфейс, описывающий дополнительные свойства для расширяемой сущности. Данному типу сущности соответствует объект метаданных EleWise.ELMA.Model.Metadata.EntityMetadata со значением свойства Type равным EntityMetadataType.InterfaceExtension.

На основе метаданных генерируется интерфейс. Пример автогенерируемого кода:

    /// <summary>
    /// Расширение пользователя для модуля ICQ
    /// </summary>
    [MetadataType(typeof(EntityMetadata))]
    [EntityMetadataType(EntityMetadataType.InterfaceExtension)]
    [Uid("07ff5f61-f3d3-4a4b-82e8-4458520f0dcc")]
    [BaseClass("04d5bcbf-4288-4d95-9745-1ebd0d690bb3")]
    public partial interface IUser_ICQExt : IUser
    {
        
        /// <summary>
        /// Номер ICQ
        /// </summary>
        string ICQ { get; set; }

    }

Реализация интерфейса сущности (Entity Interface Implementation)

Реализация интерфейса сущности – обычная сущность, реализующая интерфейс сущности, а также набор интерфейсов расширения. Данному типу сущности соответствует объект метаданных EleWise.ELMA.Model.Metadata.EntityMetadata со значением свойства Type равным EntityMetadataType.InterfaceImplementation.

Данный тип сущности не может быть создан вручную! Он генерируется автоматически при запуске системы на основе интерфейсов и интерфейсов расширения.

Пример автогенерируемого кода:

    /// <summary>
    /// Пользователь
    /// </summary>
    [MetadataType(typeof(EntityMetadata))]
    [EntityMetadataType(EntityMetadataType.InterfaceImplementation)]
    [Uid("18faf3ae-03c9-4e64-b02a-95dd63e54c4d")]
    [ImplementationUid("04d5bcbf-4288-4d95-9745-1ebd0d690bb3")]
    [Implement(typeof(IUser))]
    [Implement(typeof(IUser_ICQExt))]
    public partial class User : Entity<long>, IUser, IUser_ICQExt
    {
        
        /// <summary>
        /// Учетная запись
        /// </summary>
        public string UserName { get; set; }
        
        /// <summary>
        /// Пароль
        /// </summary>
        public string Password { get; set; }
        
        /// <summary>
        /// Номер ICQ
        /// </summary>
        public string ICQ { get; set; }

    }

Фильтры сущностей. Работа с интерфейсами сущностей

При запуске системы выбираются сущности с типами Интерфейс и Расширение интерфейса и строится сборка с именем EleWise.ELMA.DynamicModel, в которой создаются реализации интерфейсов (сущности с типом Реализация интерфейса).

Для создания экземпляра интерфейса сущности или фильтра необходимо использовать метод Create класса EleWise.ELMA.Model.Services.InterfaceActivator.

using EleWise.ELMA.Model.Services;

public class SomeClass
{

    public void SomeMethod()
    {
        var user = InterfaceActivator.Create<IUser>();
        user.UserName = "User 1";
        user.Save();
    }

}

Если необходимо получить тип реализации интерфейса сущности или фильтра, то нужно использовать метод TypeOf класса InterfaceActivator.

using EleWise.ELMA.Model.Services;

public class SomeClass
{

    public void SomeMethod()
    {
        Type userType = InterfaceActivator.TypeOf<IUser>();
    }

}

Менеджеры сущностей

Менеджер сущности – сервис, предназначенный для работы с конкретной сущностью. Он содержит все необходимые методы для работы с ней (сохранение, загрузка, поиск, различные действия и др.). Подробную информацию о менеджерах сущностей см. в статье Менеджеры сущностей.