Pergunta

Eu tenho as seguintes tabelas e entidades que precisam ser mapeadas no Fluent NHibernate.

Tabelas:

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
)

A ideia deste design de banco de dados é a seguinte:

  • Uma "área de trabalho" ou um "elemento" pode ter vários arquivos de "anexo" e um arquivo de "anexo" pode ser referido por várias "áreas de trabalho" ou "elementos".

  • Uma "área de trabalho" ou um "elemento" pode referir-se ao mesmo arquivo de "anexo".

Assim, as relações entre "anexos" e "áreas de trabalho" ou "elementos" são armazenadas em "objectattachment " quadro, no qual:

  • O campo "attachmentid" refere-se ao identificador de um "anexo" específico.

  • O campo "ApptionType" (discriminador) define se essa relação está entre "anexos" se "workeaea" ou entre "acessórios" se "elementos" s.

  • O campo "objectid" refere-se ao identificador de uma "área de trabalho" ou "elemento" específico, dependendo do valor do campo "attachmenttype" acima.

Com base no design do banco de dados, defino as classes do modelo de domínio da seguinte forma:

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; }
     }     
}

Agora, minha pergunta é se eu poderia mapear essas classes de modelo de domínio com o design de banco de dados acima.Se sim, então como eu poderia fazer isso?Se não, como altero as classes do modelo de domínio para suportar o mapeamento do Fluent NHibernate no banco de dados projetado, pois não quero alterar o design atual do banco de dados (ou seja,crie tabelas de "anexos" separadas para "área de trabalho" e "elemento").

Relação Quan

Foi útil?

Solução

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'")

Observação:você não precisa de uma coluna Id na tabela de links

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top