基于父项将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