NHibernate map for multiple parent-based tables

I am creating a domain model where objects often (but not always) have a member of type ActionLog .

ActionLog is a simple class that allows you to check the trace of actions performed on an instance. Each action is recorded as an instance of ActionLogEntry .

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

I would like to reuse this class among my entities and have records mapped to different tables, based on which class they were registered with. For instance:

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

This project is suitable for me in the application, but I don’t see a clear way to map this script to a database with NHibernate.

I usually use Fluent NHibernate for my configuration, but I am happy to accept answers in a more general HBM format.

+4
source share
2 answers

I had the same problem and it was about the same question, hoping for an answer, but I found a solution using the NH IRC channel on FreeNode.

There is a document in my script. Different things will have documents - such as reports, items, etc. The only difference between Report.Documents and Item.Documents is that the document has a reference to its owner and is mapped to another table.

The solution to this situation is mainly done through .Net. Although - I do not think that this solution would be possible with XML mappings.

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 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 where the "magic" takes place. We are going to create a generic mapping that requires the object to be used to inherit the Document class. Thus, Fluent NHibernate can still find all the properties of 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 will notice that this class does not have a reference to the table to which it is mapped, or to the parent object that every other version will use. Now we use this generic mapping for each of our special types and specify a table and map the parent object we created in each class 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 the amount of code. Now, if you want to make radical changes to the document type - you only need to change the Document class and the GenericDocumentMapping class.

In my situation - I also just bind documents to a specific table. This is done in the same way as others - inherits from GenericDocumentMapping and the table is specified. The only difference is that I am not referencing the parent.

 Public Class DocumentMapping Inherits GenericDocumentMapping(Of Document) Public Sub New() MyBase.New() Table("Documents") End Sub End Class 
+3
source

youu can use join to match it over a table

0
source

Source: https://habr.com/ru/post/1304177/


All Articles