基于父项将NHibernate实体映射到多个表

基于父项将NHibernate实体映射到多个表,nhibernate,fluent-nhibernate,Nhibernate,Fluent Nhibernate,我正在创建一个域模型,其中实体通常(但不总是)具有类型为ActionLog的成员 ActionLog是一个简单的类,它允许对实例上执行的操作进行审计跟踪。每个操作都记录为一个ActionLogEntry实例 ActionLog的实现(大致)如下: public class ActionLog { public IEnumerable<ActionLogEntry> Entries { get { return EntriesCollection;

我正在创建一个域模型,其中实体通常(但不总是)具有类型为
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.
    }
}
这个设计适合我在应用程序中使用,但是我看不到一个清晰的方法来将这个场景映射到带有NHibernate的数据库


我通常使用Fluent NHibernate进行配置,但我很乐意接受更通用的HBM xml的答案。

您可以使用join将其映射到多个表。

我遇到了同样的问题,并在发布同样的问题时希望得到答案,但我在FreeNode上的NH IRC频道的帮助下找到了解决方案

我的场景有一个文档。各种事物都会有文档,比如报表、项目等。报表文档和项目文档之间的唯一区别在于,文档有一个对其所有者的引用,并且映射到不同的表

这种情况的解决方案主要是通过.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
我认为这种方法减少了很多代码。现在,如果要对文档类型进行全面更改,只需修改
文档
类和
通用文档映射
类即可

在我的情况下,我也只是将文档映射到一个特定的表。这与其他方法相同-从
GenericDocumentMapping
继承并指定表。唯一的区别是我没有引用父对象

Public Class DocumentMapping
    Inherits GenericDocumentMapping(Of Document)
    Public Sub New()
        MyBase.New()
        Table("Documents")
    End Sub
End Class

您希望将每种类型的操作放到一个单独的表中有什么特别的原因吗?这更适合关系结构。相对而言,您有
Customers
CustomerActionLogEntries
表。与此并行的还有
Orders
OrderActionLogEntries
表。目前我的解决方案是使用一个
ActionLogEntries
表,并在NHibernate中使用具有多对多关系的联接表。这对我的口味来说有点太正常化了,需要到处加入才能获得任何有意义的数据。你有没有解决过这个问题?我将要发布相同的问题。我选择了阻力最小的路径,使用单个表(对单个类型进行建模)和多个连接表(对关系进行建模)。感谢您的回答。我找到了一个解决方案,可以利用现有的设置。让我知道你的想法。这个答案是一个合理的折衷方案,也是解决这个问题的一个相当聪明的方法。
Public Class DocumentMapping
    Inherits GenericDocumentMapping(Of Document)
    Public Sub New()
        MyBase.New()
        Table("Documents")
    End Sub
End Class