开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜