2010-03-15 118 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可以使用加入到它映射到多個表

相關問題