Mapping Revisions Table in Fluent NHibernate
I want to audit my Posts
table by preserving whole record changes to a PostRevisions
table before Post
rows are updated. PostRevision
entities should store all the Post
entity columns along with a RevisionId
column.
I want to map this with Fluent NHibernate. PostRevision
entities should mirror the properties of Post
entities, but without having to maintain two entity classes and mapping classes.
How should I de开发者_运维技巧sign my entities and mappings to do achieve this?
Desired pseudocode for Post Edit
var post = _unitOfWork.CurrentSession.Get<Post>(id);
var postRevision = new PostRevision(post);
post.Content = "changed value"; // change some things here
_unitOfWork.CurrentSession.Save(post);
_unitOfWork.CurrentSession.Save(postRevision);
_unitOfWork.Commit();
PostRevision
composition class:
public class PostRevision
{
public virtual Guid Id { get; private set; }
public virtual Post Post { get; set; }
public PostRevision()
{
}
public PostRevision(Post post)
{
this.Post = post;
}
}
Possible Fluent Mapping:
public class PostRevisionMap : ClassMap<PostRevision>
{
public PostRevisionMap()
{
Id(x => x.Id);
Component(x => x.Post); // will something like this work?
}
}
the relation (I think) you're looking for is one-to-many: a Post has many PostRevisions.
a PostRevision references a single Post.
Therefore I think the correct mapping on the Post side would be
HasMany(x=> x.PostRevisions);
and on the PostRevision side:
References(x=> x.Post).
see the nHibernate docs for a more complete look on how to map these associations.
Edit
If you want to keep a history record for each revision of your post, you have 2 options:
1. add a boolean 'IsHistoric' field to your Post class. Whenever a Post is revised, you don't change the Post object itself, but rather mark it as 'IsHistoric = true' and create a new Post object which represents the revised Post. This is the method I use in my project.
2. Create a 'HistoricPost' class which inherits from Post. You don't have to repeat your mapping, and you can use a seperate table for this class (table-per-subclass strategy).
see here for further details.
I think you can also specify a different Id column for the child class, using Id(x => x.SomeOtherId);
in the mapping of 'HistoricPost'. I haven't tried it though, so I'm not 100% sure.
精彩评论