我的模型包含一个类 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 来储存它的索引列表中的位置,它是一部分。

映在它能够流利这样的:

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

现在我能到现有的负载 Statics,我也能够更新详细的那些。然而,我似乎无法找到一种方法增加新的 Statics到 Section, 和有这种改变保留数据库。我已经尝试了几种组合:

  • mySection.Statics.Add(myStatic)
  • session.Update(mySection)
  • session.Save(myStatic)

但最近我已经(用的一两个声明),是一个SQL异常阅读:"不能插入的价值NULL列入'位'".一个清楚 INSERT 是试图在这里,但它能够似乎并不自动追加指标的位置SQL发言。

我做错了什么?我失去了一些东西在我的映射?我需要露 Position 列为一个属性,并分配一个值,它自己?

编辑: 显然一切都如预期,如果我删除了 NOT NULL 制约因素 Static.Position 列的数据库。我猜它能够使插入和立即更新后的行有 Position 值。

虽然这是一个anwers的问题,我不知道如果这是最好的之一。我会喜欢的 Position 列为不可空,因此我仍然希望有一些方法,使它能够提供一个值得列直接在 INSERT 发言。

因此,问题仍然是开放的。任何其他的解决方案?

有帮助吗?

解决方案

当使用的双向一至多关系,在它能够一端必须是"反向".最好的做法是设置的结束与集合作反,因为这避免了不必要的SQL发言,并允许id列为"not null".

第6.4节 文件你可以找到以下注:

非常重要的注意:如果列的一个协会是宣布不NULL,它能够可能导致约束侵犯时,它创建或更新协会。为了防止这个问题,你必须使用一种双向关联的许多价值的一端(设定或袋)标记为反="真实的"。看到的讨论的双向协会后来在这个章节。

所以,你需要添加。逆()你HasMany映在SectionMap.

public SectionMap()
{
    Id(x => x.Id);
    HasMany(x => x.Statics)
        .Cascade.All()
        .LazyLoad()
        .Inverse()
        .AsList(x => x.WithColumn("Position"));
}

你也可能想要添加和去除方法上的部分,其中规定/重置参考的静态以及增加或去除静态向/从其自己的收集:

public virtual void AddStatic(Static static)
{
    Statics.Add(static);
    static.Section = this;
}


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

这些方法可以确保参考文献保持的准确,在双方的关系。

根据 第6.8节 该文件它能够不支持的双向关系时使用索引集合:

请注意,它能够不支持的双向一对许多协会与一个索引,收集(列表、地图或阵列)的"许多"最后,你必须使用一套或袋映射。

所以,如果你还有问题,考虑使用一个单向的关系,而不是一个双向的,但是这可能意味着你的外键列需要nullable(根据该注意在开始时员额)。否则你可能有你的地图集作为一个袋子,或设置,而不是一个列表。

其他提示

在静态的表你有一个领域被称为"SectionID"或类似的东西。让这个领域可以为空:它能够首先增加新的记录,然后更新,引用的标识。

我发现在我的数据库,并且我感到惊讶:为什么NH不喜欢适当表的参考文献数据库的水平?

我以为我会扔在我的0.02美元,仅仅是因为我来这里寻求解决你的问题似乎没有任何答案实际工作。

你是几乎没有在你的解决方案。你的映射HasMany是正确的。问题是,如你所述的、位置没有得到更新的数据库(总的来说,当你把它设置空,它不仅"工作"因为空获取插入数据库;我这不是真的工作;)).

我发现它有点怪怪的,你需要地图上的位置你的静态级也很明显包括一个位置的财产上是静态的。你不想要的位置财产被写的,因为它的价值是通过确定在那里静是在名单。

添加以下静

public virtual int Position 
{
    get 
    {
        // Will throw exception if Section is null
        // or Section.Statics is null...
        return Section.Statics.IndexOf(this);
    }
    protected set 
    {
    }
}

这在的位置,列在该数据库将被进行更新(记住地图你的位置在你的StaticMap).

我猜的NHib代理的静态更新位置场取决于它在列表中的位置(由一些魔术大于我拥有的),然后被保存的数据库。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top