Domanda

Ho le seguenti tabelle ed entità che devono essere mappati in fluente nibernate.

Tabelle:

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
)
.

L'idea in questo design del database è la seguente:

    .
  • Una "workarea" o un "elemento" potrebbe avere diversi file "allegati" e un file "allegato" potrebbe essere definito da diversi "Sunicapara" o "elemento" s .

  • Una "workarea" o un "elemento" potrebbe fare riferimento allo stesso file "allegato".

    Quindi le relazioni tra "Attachment" s e "workarea" S o "elemento" sono memorizzate in "ObjectAttachment "Tabella, in cui:

      .
    • Il campo "attachmentment" si riferisce all'identificatore di uno specifico "attacco" s

    • "AllegatoreTyPe" Campo (discriminatore) definisce se questa relazione è tra "attaccamento" s e "workarea" o tra "attaccamento" s e "Elemento" s

    • "ObjectId" Il campo si riferisce all'identificatore di uno specifico "Elegaleare" o "elemento" S, a seconda del valore del campo "AllegatoreTyType" sopra.

      In base alla progettazione del database, definisco quindi le classi del modello di dominio come segue:

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

      Ora la mia domanda è se potrei mappatura di queste classi del modello di dominio con il design di base del database sopra. Se sì, allora come potrei farlo? Se no, in che modo, come modificare le classi del modello di dominio per supportare la mappatura del Nibernate fluente rispetto al database progettato, poiché non voglio modificare la progettazione corrente del database (cioè creare tabelle "allegati" separati per "workarea" e "elemento") .

      Saluti, QUAN

È stato utile?

Soluzione

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top