nhibernate - 限制对象层次持久性

时间:2011-07-17 22:13:38

标签: nhibernate fluent-nhibernate many-to-many

在我的应用程序中,我在Post和Tag之间有多对多的关系(用FluentNHibernate映射):

Post
{
 string Title
 List<Tag> Tags 
}

Tag
{
 string Name
 List<Post> Posts
}

映射是:

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")
                .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();
        }
    }

通过此存储库中的SaveOrUpdate进行保存:

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

当我尝试保存包含一些标签的帖子项目时,我遇到了问题,这些标签也属于其他一些问题。保存帖子导致标签失去与其他问题的关系。我想原因是;在这种情况下,我当时没有包含在Tag项目中的帖子,尽管在数据库中存在关系。

所以我想限制持久性水平。当我保存Post项时,它应该只创建关系,而不是删除Post和Tag之间的其他关系。

哪里(在映射或存储库中)以及如何实现此限制?

2 个答案:

答案 0 :(得分:0)

在你发布的配置中,Post和Tag映射类都没有告诉Fluent NHibernate哪个类负责保存关系,但是你将保存/更新从Post添加到Tag。因为这个FNH告诉PostMap处理标签的保存。

您需要通过添加Inverse()指令来指示PostMap让PostTagMap处理自己的保存操作。

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();
    }
}

请参阅此要点以获取一个工作示例:https://gist.github.com/1090085

答案 1 :(得分:0)

应将Inverse()添加到PostTagMapping中,以便将关系的所有者设置为Post。 PostTagMapping应该是这样的:

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();
}

(感谢理查德的想法)