开发者

nhibernate - limiting object hierarchy persistence

开发者 https://www.devze.com 2023-03-20 18:35 出处:网络
In my application I have many-to-many relationship (mapped with FluentNHibernate) between Post and Tag:

In my application I have many-to-many relationship (mapped with FluentNHibernate) between Post and Tag:

Post
{
 string Title
 List<Tag> Tags 
}

Tag
{
 string Name
 List<Post> Posts
}

Mappings are:

public class PostMap : ClassMap<Post>
    {
        public PostMap()
        {
            Table("Post");
            Id(x => x.Id).GeneratedBy.GuidComb();
            Map(x => x.Title);
            HasManyToMany(x => x.Tags)
                .Table("开发者_如何学JAVAPostTags")
                .ChildKeyColumn("Tag")
                .ParentKeyColumn("Post")
                .Cascade.SaveUpdate();
        }
    }

    public class PostTagMap : ClassMap<PostTag>
    {
        public PostTagMap()
        {
            Table("Tag");
            Id(x => x.Id).GeneratedBy.GuidComb();
            Map(x => x.Name);
            HasManyToMany(x => x.Posts)
                .Table("PostTags")
                .ChildKeyColumn("Post")
                .ParentKeyColumn("Tag")
                .Cascade.None();
        }
    }

Save occurs via SaveOrUpdate in this repository:

public class NHRepository : NHRepositoryBase, INHRepository
    {
        public NHRepository(IFactory factory)
            : base(factory)
        {
            this.session = this.sessionFactory.OpenSession();
        }

        public virtual TObject SaveOrUpdate<TObject>(TObject obj) where TObject : Domain.UniqueItem
        {
            var persistedObject = this.session.SaveOrUpdateCopy(obj);
            this.Commit();
            return persistedObject as TObject;
        }
}

I have a problem when I try to save Post item having some Tags, where these Tags belong to some other questions too. Saving Post causes Tags to lose their relations with other questions. I guess the reason is; in this scenario I have no Posts included in Tag items at that moment, although in database there are relations.

So I want to limit persistence level. When I save Post item it should only create relation, not to remove other relations between Post and Tag.

Where (in mapping or repository) and how I can achieve this limitation?


In your posted configuration, neither the Post nor Tag mapping classes tell Fluent NHibernate which class is responsible for saving the relationship, but you are cascading save/updates from the Post to Tag. Because of this FNH tells PostMap to handle the saving of Tags.

You need to instruct PostMap to let PostTagMap handle its own save operations by adding the Inverse() directive.

public class PostMap : ClassMap<Post>
{
    public PostMap()
    {
        Table("Post");
        Id(x => x.Id).GeneratedBy.GuidComb();
        Map(x => x.Title);
        HasManyToMany(x => x.Tags).Table("PostTags")
            .Cascade.SaveUpdate().Inverse();
    }
}

public class PostTagMap : ClassMap<Tag>
{
    public PostTagMap()
    {
        Table("Tag");
        Id(x => x.Id).GeneratedBy.GuidComb();
        Map(x => x.Name);
        HasManyToMany(x => x.Posts).Table("PostTags")
            .Cascade.None();
    }
}

See this gist for a working example: https://gist.github.com/1090085


Inverse() should be added to PostTagMapping, in order to set the owner of the relationship to be Post. PostTagMapping should be like this:

public PostTagMap()
{
    Table("Tag");
    Id(x => x.Id).GeneratedBy.GuidComb();
    Map(x => x.Name);
    HasManyToMany(x => x.Posts)
        .Table("PostTags")
        .ChildKeyColumn("Post")
        .ParentKeyColumn("Tag")
        .Cascade.None().Inverse();
}

(Thanks to Richard for the idea)

0

精彩评论

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