流利的NHibernate级联删除不起作用 [英] Fluent NHibernate cascade delete not working

查看:88
本文介绍了流利的NHibernate级联删除不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的电话目录应用程序使用流利的NHibernate 1.1。在应用程序中,Person对象具有许多PhoneNumber对象。我试图删除一个人,我想级联删除PhoneNumbers。我在阅读 DefaultCascade.All() nhibernate-automapping-old-anwser-still-valid>这个答案。然而,试图删除父对象仍然会抛出一个异常 - 看起来NHibernate试图更新子表,将父ID设置为null,而不是只删除记录:


{无法删除集合:[Person.PhoneNumbers#473] [SQL:UPDATE phone_numbers SET person_id = null WHERE person_id = @ p0]}


InnerException:


{无法将NULL值插入到'person_id ',table'directory.dbo.phone_numbers';列不允许为NULL,UPDATE失败。\r \\\
语句已被终止。}

我的Fluent配置是:

pre $ public static ISessionFactory CreateSessionFactory(){
return francently.Configure ()
.Database(MsSqlConfiguration.MsSql2008
.ConnectionString(ConfigurationManager.ConnectionStrings [ConfigurationManager.AppSettings [activeC onnStr]]。ConnectionString))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf< Person>()
.Conventions.Add(DefaultCascade.All())

.BuildSessionFactory();





父类是:
$ b $公共类Person(){
PhoneNumbers =新列表< PhoneNumber>();
EmailAddresses = new List< string>();
}

public virtual int Id {get;私人设置}
公共虚拟字符串名字{get;组; }
public virtual string LastName {get;组; }
public virtual string Company {get;组; }
公共虚拟IList< PhoneNumber> PhoneNumbers {get;组; }
公共虚拟IList< string> EmailAddresses {get;组;子类(PhoneNumber)是:$ b $






$ b

  public class PhoneNumber {
public virtual string Number {get;组; }
public virtual PhoneNumberType NumberType {get;组; }
public virtual Person Person {get;组; }
}

我的代码删除一个人是:

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





我做错了什么?

解决方案

我不确定配置Fluent的部分,但是我最近和ActiveRecord有同样的问题。



您需要在Person一方设置您的关联为 Inverse = true

查看使用入门文档.. 。

我相信,你需要在Person中定义你的HasMany关系时设置它。它应该看起来像这样:

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


I've got a simple phone directory app using Fluent NHibernate 1.1. In the app, a "Person" object has many "PhoneNumber" objects. I'm trying to delete a Person and I want to cascade deletes to PhoneNumbers. I set a convention of DefaultCascade.All() after reading this answer. However, attempting to delete the parent object still throws an exception--it appears that NHibernate is trying to update the child table to set the parent ID to null instead of just deleting the record:

{"could not delete collection: [Person.PhoneNumbers#473][SQL: UPDATE phone_numbers SET person_id = null WHERE person_id = @p0]"}

InnerException:

{"Cannot insert the value NULL into column 'person_id', table 'directory.dbo.phone_numbers'; column does not allow nulls. UPDATE fails.\r\nThe statement has been terminated."}

My Fluent config is:

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

The parent class is:

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

The child class (PhoneNumber) is:

public class PhoneNumber {
    public virtual string Number { get; set; }
    public virtual PhoneNumberType NumberType { get; set; }
    public virtual Person Person { get; set; }
}

My code to delete a person is:

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

What am I doing wrong?

解决方案

I'm not sure about configuring the Fluent part, but I recently had the same problem with ActiveRecord.

You need to set your association, on the Person side, as Inverse = true.

From looking at the Getting Started documentation...

I belive, you need to set this when defining your HasMany relationship in Person. It should look something like this:

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

这篇关于流利的NHibernate级联删除不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆