使用NHibernate维护插入时的参照完整性

时间:2010-06-22 16:47:14

标签: database nhibernate fluent-nhibernate

我已经找到了很多关于nhibernate的内容,但这似乎是我不了解正在发生的事情的最后障碍。所以这就是问题所在。

我有一个基本的数据库结构:

Shows:
ID [Pk]
CountryID [Fk]
Name

Countries:
ID [Pk]
Name

CountryID具有从显示到国家/地区表主键的foriegn键参考,并且国家/地区已填充了很少更改的预设值。

这是我的映射文件

    public ShowMap()
    {
        Table("Shows");

        Id(x => x.ID);
        Map(x => x.Name)

        HasOne<Country>(x => x.CountryOrigin)
            .Cascade.All()
            .ForeignKey("CountryID");
    }

    public CountryMap()
    {
        Table("Countries");

        Id(x => x.ID);
        Map(x => x.Name);
    }

几乎确定这是一个映射问题,但是当我插入节目并且我有一个国家附加它。 它尝试将新国家/地区插入数据库,而不是使用数据库中的现有国家这似乎是主要问题。我不知道如何在数据库中使用现有记录的情况下正确插入。

最后,这里有一个例子,我试图做一个不知道该做什么的插入。

        using (var tx = _session.BeginTransaction())
        {

            Show s1 = new Show();
            s1.CountryOrigin = new Country { ID = 2, Name = "Japan" };
            s1.Name = "Liar Game";

            _session.SaveOrUpdateCopy(s1);
            tx.Commit();
            tx.Dispose();
            return true;
        }

所以问题是如何插入新节目并让它引用国家/地区表格中的现有记录?


更新1 我已经重新设计它以使用很多关系,因为我正在阅读一个可能不是正确的方法。还有同样的问题,这里是代码更改。这些也反映了评论中的代码更改。

插入代码:

        using (var tx = _session.BeginTransaction())
        {

            Show s1 = new Show();
            s1.CountryOrigin.Add(_session.Get<Country>(2));
            s1.Name = "Liar Game";

            _session.SaveOrUpdateCopy(s1);
            tx.Commit();
            return true;
        }

映射:

    public ShowMap()
    {
        Table("Shows");

        Id(x => x.ID);
        Map(x => x.Name)

        HasMany<Country>(x => x.CountryOrigin)
            .KeyColumn("ID")
            .Cascade.SaveUpdate();
    }

    public CountryMap()
    {
        Table("Countries");

        Id(x => x.ID);
        Map(x => x.Name);
    }

仍然无法在CountryID中插入null,就像其中一条评论中提到的那样。

更新2 做一些测试/调试:

            s1.CountryOrigin.Add(_session.Get<Country>(2));

它应该做什么并获得正确的国家,但问题发生在插入。所以这让我觉得这是更多的映射问题。

2 个答案:

答案 0 :(得分:3)

你可以在国家和节目之间建立一对多的关系。因此,应使用References

映射国家/地区
public ShowMap()
{
    Table("Shows");

    Id(x => x.ID);
    Map(x => x.Name)

    References(x => x.CountryOrigin, "CountryID");
}

答案 1 :(得分:0)

您需要使用Session.Load来获取您的Country对象:

s1.CountryOrigin = _session.Load<Country>(2);

Session.Load说:“我知道数据库中存在一条带有此ID的记录。为我创建该对象的代理,无需费心去数据库”。您也可以使用Session.Get,但这会产生额外的数据库之旅。