nhibernate - 限制对象层次结构持久性

发布于 2024-11-25 06:44:17 字数 1807 浏览 7 评论 0原文

在我的应用程序中,我在 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;
        }
}

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

所以我想限制持久性级别。当我保存帖子项目时,它应该只创建关系,而不是删除帖子和标签之间的其他关系。

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

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦与时光遇 2024-12-02 06:44:17

在您发布的配置中,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

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

软的没边 2024-12-02 06:44:17

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

感谢 Richard 的想法)

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)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文