2010-10-25 165 views
17

我有一個簡單的電話目錄應用程序使用流利NHibernate的1.1。在應用程序中,「Person」對象具有許多「PhoneNumber」對象。我試圖刪除一個人,我想級聯刪除PhoneNumbers。在閱讀this answer後,我設置了一個DefaultCascade.All()的約定。但是,試圖刪除父對象仍然會拋出一個異常 - 看起來NHibernate試圖更新子表將父ID設置爲null,而不是刪除記錄:流利NHibernate級聯刪除不工作

{「無法刪除收藏:[Person.PhoneNumbers#473] [SQL:UPDATE PHONE_NUMBERS SET爲person_id = NULL WHERE爲person_id = @ P0] 「}

的InnerException:

{」 不能將NULL值插入列' person_id',表'directory.dbo.phone_numbers';列不是al低空值。更新失敗\ r \ n此語句已終止「}

我流利的配置是:。

public static ISessionFactory CreateSessionFactory() { 
    return Fluently.Configure() 
     .Database(MsSqlConfiguration.MsSql2008 
      .ConnectionString(ConfigurationManager.ConnectionStrings[ConfigurationManager.AppSettings["activeConnStr"]].ConnectionString)) 
     .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Person>() 
             .Conventions.Add(DefaultCascade.All()) 
        ) 
     .BuildSessionFactory(); 
} 

的父類是:

public class Person { 
    public Person() { 
     PhoneNumbers = new List<PhoneNumber>(); 
     EmailAddresses = new List<string>(); 
    } 

    public virtual int Id { get; private set; } 
    public virtual string FirstName { get; set; } 
    public virtual string LastName { get; set; } 
    public virtual string Company { get; set; } 
    public virtual IList<PhoneNumber> PhoneNumbers { get; set; } 
    public virtual IList<string> EmailAddresses { get; set; } 
} 

的子類(******中國)是:

​​

我的代碼刪除一個人是:

public static void DeletePerson(int id) { 
    using (var session = Dalc.Instance.SessionFactory.OpenSession()) { 
     using (var trans = session.BeginTransaction()) { 
      session.Delete(session.Load<Person>(id)); 
      trans.Commit(); 
     } 
    } 
} 

我在做什麼錯?

回答

28

我不確定配置流利部分,但我最近有與ActiveRecord相同的問題。

您需要將您在人員方面的關聯設置爲Inverse = true

從看Getting Started文檔...

我相信,你需要定義的人你的hasMany關係時設置此。它應該看起來像這樣:

public PersonMap() 
{ 
    //<...SNIP...> 
    HasMany(x => x.PhoneNumbers) 
     .Inverse(); 
    //<...SNIP...> 
} 
+0

這個伎倆。謝謝! – 2010-10-26 15:28:21

+1

反解釋:http://bchavez.bitarmory.com/archive/2007/10/06/nhibernate-and-inversetruefalse-attribute.aspx – 2012-11-23 14:26:47

+0

感謝您的鏈接來解釋'Invserse'。我希望父母擁有孩子,但這不是這種情況。 – Jess 2015-02-13 17:47:17

20

它的工作;以下是每個級聯選項的含義:

- 不要做任何級聯,讓用戶自己處理它們。

保存更新 - 當對象被保存/更新時,檢查關聯並保存/更新任何需要它的對象(包括保存/更新多對多關聯中的關聯)。

刪除 - 當對象被刪除時,刪除關聯中的所有對象。

delete-orphan - 刪除對象時,刪除關聯中的所有對象。除此之外,當一個對象從關聯中刪除並且不與另一個對象(孤立的)關聯時,也將其刪除。

全部 - 當一個對象是保存/更新/刪除時,檢查關聯並保存/更新/刪除找到的所有對象。

all-delete-orphan - 當對象爲save/update/delete時,檢查關聯並保存/更新/刪除找到的所有對象。除此之外,當一個對象從關聯中刪除並且與另一個對象(孤立的)沒有關聯時,也刪除它。

public class PersonMap : ClassMap<Person> 
{ 
    public PersonMap() 
    { 
     Table("Person"); 

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

     HasMany<PhoneNumber>(x => x.PhoneNumberList) 
      .KeyColumn("PersonId") 
      .Cascade.All() 
      .Inverse().LazyLoad(); 
    } 
} 
+0

+1是我見過的'cascade'選項的最簡潔解釋。謝謝! – 2013-04-19 21:56:10