2010-03-15 82 views
4

我创建了一个域模型,其中实体经常(但不总是)具有类型ActionLog类型的成员。将NHibernate实体映射到基于父项的多个表

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的数据库。

我通常使用流利NHibernate的配置,但我很高兴接受更普遍的HBM XML中的答案。

+0

是否有一个特定的原因,你希望每种类型的行动去一个单独的表? – 2010-03-15 17:24:32

+0

这对于关系结构来说更自然。相关地,你有'Customers'和'CustomerActionLogEntries'表。与此相对,您有'订单'和'OrderActionLogEntries'表。目前我的解决方案是使用一个'ActionLogEntries'表,并且在NHibernate中使用具有多对多关系的连接表。这对我的口味来说有点过于规范,要求全面加入以获取任何有意义的数据。 – 2010-03-16 09:33:52

+0

你有没有得到这个决议?我即将发布相同的问题。 – Origin 2011-12-26 21:57:42

回答

3

我有同样的问题,是关于后同样的问题,希望一个答案 - 但我发现与NH IRC的帮助下,解决方案频道在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仍然可以找到从Document继承的对象的所有属性。

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

这个答案提出了一个合理的妥协和相当聪明的方法来解决这个问题。 – 2011-12-29 09:30:56

0

youu可以使用加入到它映射到多个表

相关问题