유창한 nhibernate : DeCriiminator와 많은 관계를 매핑하는 방법
문제
나는 유창한 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
)
.
이 데이터베이스 디자인의 아이디어는 다음과 같습니다.
-
a "workarea"또는 "요소"는 여러 "첨부 파일"파일을 가질 수 있고 "첨부 파일"파일을 여러 "WorkArea"s 또는 "요소"로 참조 할 수 있습니다. 리>
-
"Workarea"또는 "요소"는 동일한 "첨부 파일"파일을 참조 할 수 있습니다.
"첨부 파일"과 "Workarea"또는 "요소"사이의 관계는 "objectattachment에 저장됩니다. "테이블, 그 안에 :
-
"AttachmentId"필드는 특정 "첨부 파일"의 식별자를 나타냅니다.
-
"AttachmentType"필드 (Discriminator)는이 관계의 여부를 정의합니다. "첨부 파일"과 "Workarea"또는 "첨부 파일"사이에 있습니다. "요소"
-
"ObjectID"필드는 위의 "AttachmentType"필드의 값에 따라 특정 "Workarea"s 또는 "요소"의 식별자를 나타냅니다.
데이터베이스 디자인을 기반으로 한 다음 다음과 같이 도메인 모델 클래스를 정의합니다.
.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 매핑을 지원하도록 도메인 모델 클래스를 변경하여 현재 데이터베이스 디자인 ( "Workarea"및 "요소"에 대한 "첨부 파일"테이블 만들기) .
조사, 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