【问题标题】:Maintaining Referential Integrity on Insert with NHibernate使用 NHibernate 维护插入时的引用完整性
【发布时间】:2011-03-06 22:23:39
【问题描述】:

我对 nhibernate 有了很多了解,但这似乎是我不了解发生了什么的最后一个障碍。那么问题来了。

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

Shows:
ID [Pk]
CountryID [Fk]
Name

Countries:
ID [Pk]
Name

CountryID 具有从节目到国家表主键的外键引用,并且国家已经填充了很少更改的预设值。

这是我的映射文件

    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 我已对其进行了重新设计以使用多关系,因为我读到多关系可能不是正确的方法。仍然有同样的问题,这里是代码更改。这些也反映了 cmets 中的代码更改。

插入代码:

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

仍然无法像其中一个 cmets 中提到的那样将 null 插入 CountryID。

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

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

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

【问题讨论】:

  • 只是一个迂腐的观点:你不需要tx.Dispose()using 语句将为您调用 Dispose()
  • 即使我在 tx.dispose 之后返回 true 也是如此吗?

标签: database nhibernate fluent-nhibernate


【解决方案1】:

您在国家/地区之间建立了一对多的关系,并在多方面进行了表演。所以 Country 应该使用References 映射:

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

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

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

【讨论】:

  • 谢谢你解决了它。你对它的描述实际上让我更好地理解了参考是如何工作的。简短而简单的解释。谢谢。
【解决方案2】:

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

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

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

【讨论】:

  • 这就是我在阅读时的想法,但是当我尝试该代码时,我得到了。 “无法将值 NULL 插入到列 'CountryID'”作为插入错误。这就是我如此困惑的原因。尽管我认为我找到了答案,而传统观点认为它应该有效,但它没有。
猜你喜欢
  • 1970-01-01
  • 2011-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-26
  • 2011-06-15
  • 2013-08-01
  • 2019-04-20
相关资源
最近更新 更多