gpt4 book ai didi

nhibernate - 如何将新对象添加到与 NHibernate 一对多映射的 IList?

转载 作者:行者123 更新时间:2023-12-03 12:38:01 25 4
gpt4 key购买 nike

我的模型包含一个类 Section其中有一个有序列表 Statics这是本节的一部分。抛开所有其他属性,模型的实现如下所示:

public class Section
{
public virtual int Id { get; private set; }
public virtual IList<Static> Statics { get; private set; }
}

public class Static
{
public virtual int Id { get; private set; }
}

在数据库中,关系被实现为一对多,其中表 Static有一个外键指向 Section和一个整数列 Position将其索引位置存储在它所属的列表中。

映射是在 Fluent NHibernate 中完成的,如下所示:
public SectionMap()
{
Id(x => x.Id);
HasMany(x => x.Statics).Cascade.All().LazyLoad()
.AsList(x => x.WithColumn("Position"));
}

public StaticMap()
{
Id(x => x.Id);
References(x => x.Section);
}

现在我可以加载现有的 Static s,我也可以更新这些细节。但是,我似乎找不到添加新 Static 的方法。 s 到 Section ,并将此更改保留到数据库中。我尝试了以下几种组合:
  • mySection.Statics.Add(myStatic)
  • session.Update(mySection)
  • session.Save(myStatic)

  • 但我得到的最接近的(使用前两个语句)是 SQL 异常读数:“无法将 NULL 值插入列 'Position'”。显然是 INSERT在这里尝试,但 NHibernate 似乎不会自动将索引位置附加到 SQL 语句。

    我究竟做错了什么?我的映射中是否缺少某些内容?我需要暴露 Position吗?列作为属性并自己为其分配值?

    编辑:显然,如果我删除 NOT NULL,一切都按预期工作 Static.Position 上的约束数据库中的列。我猜 NHibernate 会在用 Position 更新行后立即进行插入和操作。值(value)。

    虽然这是对问题的回答,但我不确定它是否是最好的。我更喜欢 Position列不可为空,所以我仍然希望有某种方法可以让 NHibernate 直接在 INSERT 中为该列提供值陈述。

    因此,这个问题仍然悬而未决。还有其他解决方案吗?

    最佳答案

    在 NHibernate 中使用双向一对多关系时,一端必须是“反向”。最佳实践是将集合的结尾设置为反向,因为这样可以避免不必要的 SQL 语句并允许 id 列“非空”。

    section 6.4在文档中,您可以找到以下注释:

    Very Important Note: If the column of a association is declared NOT NULL, NHibernate may cause constraint violations when it creates or updates the association. To prevent this problem, you must use a bidirectional association with the many valued end (the set or bag) marked as inverse="true". See the discussion of bidirectional associations later in this chapter.



    因此,您需要将 .Inverse() 添加到 SectionMap 中的 HasMany 映射中。
    public SectionMap()
    {
    Id(x => x.Id);
    HasMany(x => x.Statics)
    .Cascade.All()
    .LazyLoad()
    .Inverse()
    .AsList(x => x.WithColumn("Position"));
    }

    您可能还需要在 Section 上使用 Add 和 Remove 方法,该方法设置/重置静态的引用以及向/从其自己的集合添加/删除静态:
    public virtual void AddStatic(Static static)
    {
    Statics.Add(static);
    static.Section = this;
    }


    public virtual void RemoveStatic(Static static)
    {
    Statics.Remove(static);
    static.Section = null;
    }

    这些方法确保引用在关系的双方都保持准确。

    根据 section 6.8的文档 NHibernate 在使用索引集合时不支持双向关系:

    Please note that NHibernate does not support bidirectional one-to-many associations with an indexed collection (list, map or array) as the "many" end, you have to use a set or bag mapping.



    因此,如果您仍然遇到问题,请考虑使用单向关系而不是双向关系,但这可能意味着您的外键列需要可以为空(根据帖子开头的说明)。否则,您可能需要将您的收藏映射为包或套装而不是列表。

    关于nhibernate - 如何将新对象添加到与 NHibernate 一对多映射的 IList?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1253490/

    25 4 0