gpt4 book ai didi

nhibernate - 将 NHibernate 实体映射到基于父级的多个表

转载 作者:行者123 更新时间:2023-12-03 16:49:11 25 4
gpt4 key购买 nike

我正在创建一个域模型,其中实体通常(但不总是)具有类型 ActionLog 的成员.
ActionLog是一个简单的类,它允许对在实例上执行的操作进行审计跟踪。每个 Action 都记录为 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 中的答案。

最佳答案

我遇到了同样的问题,并且正在发布同样的问题,希望得到答案 - 但我在 FreeNode 上的 NH IRC channel 的帮助下找到了解决方案。

我的场景有一个文档。各种东西都会有文档——比如报告、项目等。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

然后我们为每个额外的 Document 类型从这个类继承:
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类(class)。

在我的情况下 - 我也只是将 Documents 映射到特定的表。这样做的方式与其他方法相同 - 从 GenericDocumentMapping 继承并指定表。唯一的区别是我不引用父对象。
Public Class DocumentMapping
Inherits GenericDocumentMapping(Of Document)
Public Sub New()
MyBase.New()
Table("Documents")
End Sub
End Class

关于nhibernate - 将 NHibernate 实体映射到基于父级的多个表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2448935/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com