Сопоставить сущность NHibernate с несколькими таблицами на основе родительского - PullRequest
4 голосов
/ 15 марта 2010

Я создаю модель домена, в которой сущности часто (но не всегда) имеют член типа ActionLog.

ActionLog - это простой класс, который позволяет отслеживать действия, выполняемые с экземпляром. Каждое действие записывается как экземпляр ActionLogEntry.

ActionLog реализован (приблизительно) следующим образом:

public class ActionLog
{   
    public IEnumerable<ActionLogEntry> Entries
    {
        get { return EntriesCollection; }
    }

    protected ICollection<ActionLogEntry> EntriesCollection { get; set; }

    public void AddAction(string action)
    {
        // Append to entries collection.
    }
}

Я хотел бы повторно использовать этот класс среди моих сущностей и сделать так, чтобы записи отображались в разных таблицах в зависимости от того, в каком классе они зарегистрированы. Например:

public class Customer
{
    public ActionLog Actions { get; protected set; }
}

public class Order
{
    public ActionLog Actions { get; protected set; }
}

Этот дизайн подходит для меня в приложении, однако я не вижу четкого способа сопоставить этот сценарий с базой данных с помощью NHibernate.

Обычно я использую Fluent NHibernate для своей конфигурации, но я рад принять ответы в более общем виде в формате HBM xml.

Ответы [ 2 ]

3 голосов
/ 29 декабря 2011

У меня была та же проблема, и я писал о том же вопросе, надеясь на ответ, - но я нашел решение с помощью канала IRC NH на FreeNode.

В моем сценарии есть Документ. Документы могут быть разными - например, отчеты, элементы и т. Д. Единственное отличие между Report.Documents и Item.Documents состоит в том, что документ имеет ссылку на своего владельца и сопоставлен с другой таблицей.

Решение для этой ситуации в основном достигается через .Net. Хотя - я не думаю, что это решение было бы возможным с отображениями XML.

Класс документа:

Public Class Document
    Public Overridable Property DocumentId As Integer
    Public Overridable Property Directory As String
    Public Overridable Property Name As String
    Public Overridable Property Title As String
    Public Overridable Property Revision As String
    Public Overridable Property Description As String
    Public Overridable Property Owner As String
    Public Overridable Property UploadedBy As String
    Public Overridable Property CreationDate As Date
    Public Overridable Property UploadDate As Date
    Public Overridable Property Size As Int64
    Public Overridable Property Categories As String
End Class

Затем мы наследуем от этого класса для каждого из наших дополнительных типов документов:

Public Class ReportDocument
    Inherits Document
    Public Overridable Property Report As Report
End Class

Public Class ItemDocument
    Inherits Document
    Public Overridable Property Item As Item
End Class

Вот где происходит "волшебство". Мы собираемся создать общее отображение, которое требует, чтобы используемый объект наследовал класс Document. Таким образом, Fluent NHibernate по-прежнему может находить все свойства объектов, которые наследуются от Документа.

Public Class GenericDocumentMapping(Of T As Document)
    Inherits ClassMap(Of T)
    Public Sub New()
        Id(Function(x) x.DocumentId)
        Map(Function(x) x.Directory)
        Map(Function(x) x.Name)
        Map(Function(x) x.Title).Not.Nullable()
        Map(Function(x) x.Revision)
        Map(Function(x) x.Description)
        Map(Function(x) x.Owner)
        Map(Function(x) x.UploadedBy)
        Map(Function(x) x.CreationDate).Not.Nullable()
        Map(Function(x) x.UploadDate).Not.Nullable()
        Map(Function(x) x.Size)
        Map(Function(x) x.Categories)
    End Sub
End Class

Вы заметите, что этот класс не имеет ссылки на таблицу, в которую он отображается, и на родительский объект, который будет использовать каждая другая версия. Теперь мы используем это общее отображение для каждого из наших специальных типов, определяем таблицу и сопоставляем родительский объект, который мы создали, в каждом типе класса, который мы создали.

Public Class ReportDocumentMapping
    Inherits GenericDocumentMapping(Of ReportDocument)
    Public Sub New()
        MyBase.New()
        References(Function(x) x.Item).Column("ReportID")
        Table("ReportDocuments")
    End Sub
End Class

Public Class ItemDocumentMapping
    Inherits GenericDocumentMapping(Of ItemDocument)
    Public Sub New()
        MyBase.New()
        References(Function(x) x.Item).Column("ItemID")
        Table("ItemDocuments")
    End Sub
End Class

Я думаю, что этот метод уменьшает объем кода. Теперь, если вы хотите внести быстрые изменения в тип документа - вам нужно только изменить класс Document и класс GenericDocumentMapping.

В моей ситуации - я также просто сопоставляю документы с определенной таблицей. Это делается так же, как и другие - наследование от GenericDocumentMapping и указание таблицы. Разница лишь в том, что я не ссылаюсь на родительский объект.

Public Class DocumentMapping
    Inherits GenericDocumentMapping(Of Document)
    Public Sub New()
        MyBase.New()
        Table("Documents")
    End Sub
End Class
0 голосов
/ 19 июня 2010

Вы можете использовать объединение, чтобы сопоставить его с более чем таблицей

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...