Свободное владение Nibernate: как набрать многие отношения с дискриминатором

StackOverflow https://stackoverflow.com/questions/9511985

Вопрос

У меня есть следующие таблицы и объекты, которые должны быть сопоставлены в свободном режиме Nhibernate.

Таблицы:

CREATE TABLE workarea
(
  id uuid NOT NULL,
  name character varying(255) NOT NULL,
  CONSTRAINT pk_workarea PRIMARY KEY (id),
)

CREATE TABLE element
(
  id uuid NOT NULL,
  name character varying(255) NOT NULL,
  CONSTRAINT pk_element PRIMARY KEY (id),
)

CREATE TABLE attachment
(
  id uuid NOT NULL,
  filename character varying(255) NOT NULL,
  CONSTRAINT pk_attachment PRIMARY KEY (id),
)  

CREATE TABLE objectattachment
(
  id uuid NOT NULL,
  attachmentid uuid NOT NULL,
  attachmenttype string NOT NULL,
  objectid uuid NOT NULL,
  CONSTRAINT pk_objectattachment PRIMARY KEY (id),
  CONSTRAINT fk_oa_a FOREIGN KEY (attachmentid)
      REFERENCES attachment (id) MATCH SIMPLE
      ON UPDATE RESTRICT ON DELETE RESTRICT,
  CONSTRAINT fk_oa_at FOREIGN KEY (attachmenttypeid)
      REFERENCES attachmenttype (id) MATCH SIMPLE
      ON UPDATE RESTRICT ON DELETE RESTRICT
)
.

Идея по этой конструкции базы данных выглядит следующим образом:

    .
  • "Workarea" или «элемент» может иметь несколько файлов вложения «вложения», и файл «вложения» можно упомянуть на несколько «рабочих» или «элемент» или «элемент»

  • "Workarea" или «элемент» может относиться к тому же «вложению» файла.

    Таким образом, отношения между «прикреплением» и «рабочими» S или «элементами» хранятся в «Объединении» «Таблица, в которой:

      .
    • "ATTATCEMENTID" относится к идентификатору определенного «прикрепления».

    • "AttachmentType" Поле (дискриминатор) определяет ли это отношение между «прикреплением» и «рабочие» S или между «привязанностью» и "Элемент" s. Поле

    • "objectiD" относится к идентификатору определенной «рабочей обработки» или «элемента» или «элемента рабочей сети», в зависимости от значения приведенного выше поля «ATCATCEMENTTYPE».

      На основании дизайна базы данных я затем определяю классы моделей домена следующим образом:

      public class WorkArea    
      {
           private Guid _id = Guid.Empty;
           private string _name;
           public virtual Guid Id     
           {
                get { return _id ; }
                set { _id = value; }
           }
           public virtual string Name     
           {
                get { return _name ; }
                set { _name = value; }
           }
      }
      
      public class Element    
      {
           private Guid _id = Guid.Empty;
           private string _name;
           public virtual Guid Id     
           {
                get { return _id ; }
                set { _id = value; }
           }
           public virtual string Name     
           {
                get { return _name ; }
                set { _name = value; }
           }
      }
      
      public class Attachment
      {
           private Guid _id = Guid.Empty;
           private string _fileName;
           public virtual Guid Id     
           {
                get { return _id ; }
                set { _id = value; }
           }
           public virtual string FileName     
           {
                get { return _fileName; }
                set { _fileName= value; }
           }
      }
      
      public class WorkAreaAttachment : Attachment
      {
           private WorkArea _workArea;
           public virtual WorkArea WorkArea 
           {
                get { return _workArea; }
                set { _workArea = value; }
           }     
      }
      
      public class ElementAttachment : Attachment
      {
           private Element _element;
           public virtual Element Element
           {
                get { return _element; }
                set { _element = value; }
           }     
      }
      
      .

      Теперь мой вопрос заключается в том, мог ли я отображать эти классы моделей домена с вышеуказанным дизайном базы данных. Если да, то как я мог это сделать? Если нет, то как я могу изменить классы моделей домена, чтобы поддержать сопоставление беглых NHIBERNATE против разработанной базы данных, так как я не хочу менять текущую конструкцию базы данных (т. Е. Создание отдельных таблиц вложения для «рабочие» и «элемент»). ,

      С уважением, Quan

Это было полезно?

Решение

public class AttachmentLink
{
     private Attachment _attachment;
     public virtual Attachment Parent
     {
          get { return _attachment; }
          set { _attachment = value; }
     }

     private IHasAttachments _linkedTo;
     public virtual IHasAttachments LinkedTo
     {
          get { return _linkedTo; }
          set { _linkedTo = value; }
     }
}

// in AttachmentMap
HasMany(x => x.Links)
    .Table("objectattachment");

// map the component
sealed class AttachmentLinkMap : ComponentMap<AttachmentLink>
{
    public AttachmentLinkMap()
    {
        References(x => x.Attachment, "attachmentid");
        ReferencesAny(x => x.LinkedTo)
            .IdentityType<Guid>()
            .EntityIdentifierColumn("objectid")
            .EntityTypeColumn("attachmenttype")
            .AddMetaValue<WorkArea>(typeof(WorkArea).Name.ToLower())
            .AddMetaValue<Element>(typeof(Element).Name.ToLower())
            .Not.LazyLoad();  // to prevent false proxies
    }
}


// in ElementMap, and almost the same in WorkAreaMap
HasManyToMany(x => x.Attachments)
    .Where("attachmenttype='element'")

Note: you don't need an Id column in the link table

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top