根据父级将 NHibernate 实体映射到多个表

发布于 2024-08-25 17:55:02 字数 886 浏览 4 评论 0原文

我正在创建一个域模型,其中实体通常(但并非总是)具有 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.
    }
}

我想要的是在我的实体中重用此类,并根据记录的类将条目映射到不同的表。例如:

public class Customer
{
    public ActionLog Actions { get; protected set; }
}

public class Order
{
    public ActionLog Actions { get; protected set; }
}

这种设计在应用程序中适合我,但是我看不到一种清晰的方法来将此场景映射到带有 NHibernate 的数据库。

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

I'm creating a domain model where entities often (but not always) have a member of type ActionLog.

ActionLog is a simple class which allows for an audit trail of actions being performed on an instance. Each action is recorded as an ActionLogEntry instance.

ActionLog is implemented (approximately) as follows:

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.
    }
}

What I would like is to re-use this class amongst my entities and have the entries map to different tables based on which class they are logged against. For example:

public class Customer
{
    public ActionLog Actions { get; protected set; }
}

public class Order
{
    public ActionLog Actions { get; protected set; }
}

This design is suitable for me in the application, however I can't see a clear way to map this scenario to a database with NHibernate.

I typically use Fluent NHibernate for my configuration, but I'm happy to accept answers in more general HBM xml.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

厌味 2024-09-01 17:55:02

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

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

I was having the same problem and was about the post the same question hoping for an answer - but I found the solution with the help of the NH IRC channel on FreeNode.

My scenario has a Document. Various things will have Documents - like Reports, Items, etc. The only difference between Report.Documents and Item.Documents is that the document has a reference to its owner, and it is mapped to a different table.

The solution for this situation is mostly accomplished through .Net. Though - I don't think this solution would be possible with XML mappings.

The Document Class:

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

Then we inherit from this class for each of our additional Document types:

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

Here's where the "magic" happens. We're going to create a generic mapping that requires that the object being used inherits the Document class. This way, Fluent NHibernate can still find all the properties on the objects that inherit from the 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

You'll notice that this class has no reference to which table it is being mapped to, nor the parent object that each different version will use. Now, we use this generic mapping for each of our special types, and specify the table and map the parent object we created in each class type we created.

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

I think this method reduces a lot of code. Now, if you want to make sweeping changes to the document type - you only have to modify the Document class, and the GenericDocumentMapping class.

In my situation - I also just map Documents to a specific table. This is done the same way as the others - inherit from the GenericDocumentMapping and specify the table. The only difference is I don't reference a parent object.

Public Class DocumentMapping
    Inherits GenericDocumentMapping(Of Document)
    Public Sub New()
        MyBase.New()
        Table("Documents")
    End Sub
End Class
忘你却要生生世世 2024-09-01 17:55:02

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

youu can use join to map it to more than table

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文