2010-10-25 101 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