2009-09-21 61 views
3

我遇到了一對多關係的問題。我有以下域類:流利的nHibernate:一對多關係問題

public class Installation : Entity<Installation> 
{   
    public virtual string Name { get; set; } 
    public virtual IList<Institution> Institutions { get; set; } 

    public Installation() 
    { 
     Institutions = new List<Institution>(); 
    } 
} 
public class Institution : Entity 
{ 
    public virtual string Name { get; set; } 
    public virtual string Address { get; set; } 
    public virtual string City { get; set; } 
    public virtual Installation Installation { get; set; }   
} 

我照着以下post作出的實體基類。我有以下映射定義:以下列方式

public class InstitutionMapping : ClassMap<Institution> 
{ 
    public InstitutionMapping() 
    { 
     WithTable("Institution"); 
     Id(i => i.Id).GeneratedBy.Guid(); 
     Map(i => i.Name).Not.Nullable().WithLengthOf(50); 
     Map(i => i.Address).Not.Nullable().WithLengthOf(50); 
     Map(i => i.City).Not.Nullable().WithLengthOf(50); 
     References(i => i.Installation).ColumnName("InstallationId").Not.Nullable().WithForeignKey(); 
    } 
} 

public class InstallationMapping : ClassMap<Installation> 
{ 
    public InstallationMapping() 
    { 
     WithTable("Installation"); 
     Id(i => i.Id).GeneratedBy.Guid(); 
     Map(i => i.Name).Not.Nullable().WithLengthOf(50); 
     HasMany<Institution>(i => i.Institutions).KeyColumnNames.Add("InstallationId").Inverse().Cascade.All(); 
    } 
} 

我的單元測試增加機構的安裝:

Installation installation = TestHelper.CreateAnonymousInstallation(); 
installation.Institutions.Add(TestHelper.CreateAnonymousInstitution()); 
installation.Institutions.Add(TestHelper.CreateAnonymousInstitution()); 
session.Save(installation);  
session.Flush(); 
session.Clear(); 
Installation returnedInstallation = session.Get<Installation>(installation.Id); 
Assert.AreEqual(2, returnedInstallation.Institutions.Count); 

我得到一個斷言異常,因爲機構的回數爲0。我有在SQL事件探查器中檢查並且機構保存在數據庫中,但其InstallationId爲空。有人能告訴我我做錯了什麼嗎?

+0

http://stackoverflow.com/questions/713637/inverse-attribute-in-nhibernate – 2009-09-21 18:16:20

回答

5

當你有inverse="false"一個持久化集合,然後父對象擁有的關係,任何改變父母的收集將是反映在數據庫中。

當您有一個持續集合inverse="true"時,那麼子對象擁有該關係,並且對子對父對象的引用的任何更改都將反映在數據庫中。

因爲您設置了inverse="true",您需要將子對象的引用更改爲父對象,以便NHibernate選擇它。如果您希望NHibernate在您將子項添加到父項集合中或從父項集合中刪除子項時接收關係的更改,則必須在集合上設置inverse="false"

+0

的確,當沒有Not.Nullable()並且PatronId可能爲null時,它解決了我的問題。如果在我的單元測試中保存安裝的情況並非如此,則會出現以下錯誤: 「NHibernate.PropertyValueException:not-null屬性引用空值或瞬態值」。 如何克服這個問題? – GUZ 2009-09-21 13:33:30

+0

答案是:你應該總是改變雙方的關係。每次設置孩子的父親引用並將孩子添加到父代的集合中。無論您每次分兩步執行此操作,還是您採用某種透明的方式完成此操作,都取決於您。 – yfeldblum 2009-09-21 22:15:28

+0

我明白。我還有一個問題:我使用PersistenceSpecification單元測試映射。在驗證映射時,Institution CheckList方法也會拋出NHibernate.PropertyValueException:「非空屬性引用null或瞬態值」。如何在需要更改關係的雙方時使用PersistenceSpecification? – GUZ 2009-09-22 06:13:30

1

您必須手動設置機構的安裝特性,具體而言,

Installation installation = TestHelper.CreateAnonymousInstallation(); 
Institution institution = TestHelper.CreateAnonymousInstitution(); 
institution.Installation = installation; 
installation.Institutions.Add(institution); 
+0

請記住,nh不會自動同步雙向關係。 – epitka 2009-09-21 13:02:47

+0

我知道你的解決方案有效。不過,我認爲,在正常的雙向關係的情況下,NHibernate應該自動執行該操作。有什麼方法可以配置解決方案,以便只需要將孩子添加到收藏夾而無需設置父母引用? – GUZ 2009-09-21 13:03:06

+0

是的。不要設置'inverse =「true」'。但是,如果你直接設置孩子對父母的引用,而不是將孩子添加到父母的集合中,NHibernate可能不會修改關係。 – yfeldblum 2009-09-21 13:14:00

相關問題