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

nhibernate-限制对象层次结构持久性,nhibernate,fluent-nhibernate,many-to-many,Nhibernate,Fluent Nhibernate,Many To Many,在我的应用程序中,Post和Tag之间存在多对多关系(使用FluentNHibernate映射): Post { string Title List<Tag> Tags } Tag { string Name List<Post> Posts } Post { 字符串标题 列表标签 } 标签 { 字符串名 列出职位 } 映射为: public class PostMap : ClassMap<Post> { public

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

Post
{
 string Title
 List<Tag> Tags 
}

Tag
{
 string Name
 List<Post> Posts
}
Post
{
字符串标题
列表标签
}
标签
{
字符串名
列出职位
}
映射为:

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();
        }
    }
public class PostMap:ClassMap
{
公共邮戳(
{
表(“员额”);
Id(x=>x.Id).GeneratedBy.GuidComb();
地图(x=>x.Title);
HasManyToMany(x=>x.Tags)
.表格(“PostTags”)
.ChildKeyColumn(“标记”)
.ParentKeyColumn(“Post”)
.Cascade.SaveUpdate();
}
}
公共类PostTagMap:ClassMap
{
公共PostTagMap()
{
表(“标签”);
Id(x=>x.Id).GeneratedBy.GuidComb();
Map(x=>x.Name);
HasManyToMany(x=>x.Posts)
.表格(“PostTags”)
.ChildKeyColumn(“Post”)
.ParentKeyColumn(“标记”)
.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;
        }
}
公共类NHRepository:NHRepositoryBase,INHRepository
{
公共存储库(IFactory工厂)
:基地(工厂)
{
this.session=this.sessionFactory.OpenSession();
}
公共虚拟TObject SaveOrUpdate(TObject obj),其中TObject:Domain.UniqueItem
{
var persistedObject=this.session.SaveOrUpdateCopy(obj);
this.Commit();
将persistedObject作为TObject返回;
}
}
当我试图保存带有一些标签的帖子时,我遇到了一个问题,这些标签也属于其他问题。保存帖子会导致标记失去与其他问题的关系。我想原因是;在这个场景中,虽然在数据库中存在关系,但此时标记项中并没有包含帖子

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


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

在发布的配置中,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();
    }
}
public class PostMap:ClassMap
{
公共邮戳(
{
表(“员额”);
Id(x=>x.Id).GeneratedBy.GuidComb();
地图(x=>x.Title);
HasManyToMany(x=>x.Tags).Table(“PostTags”)
.Cascade.SaveUpdate().Inverse();
}
}
公共类PostTagMap:ClassMap
{
公共PostTagMap()
{
表(“标签”);
Id(x=>x.Id).GeneratedBy.GuidComb();
Map(x=>x.Name);
HasManyToMany(x=>x.Posts).Table(“PostTags”)
.Cascade.None();
}
}

请参阅此要点以获得一个工作示例:

在发布的配置中,Post和标记映射类都不会告诉Fluent NHibernate哪个类负责保存关系,但您正在将保存/更新从Post级联到标记。因此,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();
    }
}
public class PostMap:ClassMap
{
公共邮戳(
{
表(“员额”);
Id(x=>x.Id).GeneratedBy.GuidComb();
地图(x=>x.Title);
HasManyToMany(x=>x.Tags).Table(“PostTags”)
.Cascade.SaveUpdate().Inverse();
}
}
公共类PostTagMap:ClassMap
{
公共PostTagMap()
{
表(“标签”);
Id(x=>x.Id).GeneratedBy.GuidComb();
Map(x=>x.Name);
HasManyToMany(x=>x.Posts).Table(“PostTags”)
.Cascade.None();
}
}
有关工作示例,请参见本要点:

应将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()添加到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的创意)

你能不能也发布地图?以及你是如何使用它的。Rui和Diego,我已经更新了这个问题。你如何获得添加到帖子中的标签。标签集合?NHibernate不应该接触未初始化的集合。请您也发布映射?以及您如何使用它。Rui和Diego,我已经更新了问题。您如何获得添加到post的标记。标记集合?NHibernate不应触摸未初始化的集合确保检查生成的SQL。如果在执行插入操作之前先执行一组删除操作,则可能需要将Inverse()更改为其他映射。请确保检查生成的SQL。如果在插入操作之前获得一组删除操作,则可能需要将Inverse()更改为其他映射。