Свободное владение Nibernate: как набрать многие отношения с дискриминатором
Вопрос
У меня есть следующие таблицы и объекты, которые должны быть сопоставлены в свободном режиме 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