2010-06-22 55 views
3

我已经弄清楚了很多关于nhibernate的内容,但这似乎是我不知道发生了什么的最后一个障碍。所以这是问题。用NHibernate插入时保持引用完整性

我有一个基本的databas结构:

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。

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

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

请问什么是应该做的,并得到了正确的国家,但问题发生在插入。所以这使我认为这是更多的映射问题。

+0

只是一个迂腐点:你不需要'tx.Dispose()'。 'using'语句会为你调用Dispose()。 – 2010-06-22 17:05:58

+0

即使我在tx.dispose之后返回true,也是如此吗? – percent20 2010-06-22 17:09:11

+0

是的,它仍然会处置。 – 2010-06-22 17:34:52

回答

3

您在国家和节目之间拥有一对多的关系,并在多方面展示。所以国家应该使用映射References

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

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

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

谢谢,这是什么解决它。而你对它的描述实际上使我更好地理解参考是如何工作的。好的简短的解释。谢谢。 – percent20 2010-06-22 18:26:10

0

您需要使用Session.Load让你的国家目标:

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

Session.Load说:“我知道,一个记录与该ID数据库存在我创建对象的代理,而不必去数据库“。你也可以使用Session.Get,但这会创建一个额外的数据库之旅。

+0

这就是我在读的时候的想法,但是当我尝试获得的代码时。 “无法将值NULL插入到'CountryID'列中作为插入错误。这就是我很困惑的原因。尽管我认为我找到了答案,而传统的智慧说它应该起作用,但事实并非如此。 – percent20 2010-06-22 17:16:37