isessionfactory fluently c# fluent-nhibernate

c# - fluently - Fluido NHibernate en cascada eliminar no funciona



nhibernate c# (2)

Tengo una aplicación de directorio telefónico simple que usa Fluent NHibernate 1.1. En la aplicación, un objeto "Persona" tiene muchos objetos "Número de teléfono". Estoy tratando de eliminar una persona y quiero eliminar en cascada los números de teléfono. Establecí una convención de DefaultCascade.All() después de leer esta respuesta . Sin embargo, al intentar eliminar el objeto principal aún se produce una excepción: parece que NHibernate está intentando actualizar la tabla secundaria para establecer el ID principal en nulo en lugar de simplemente eliminar el registro:

{"no se pudo eliminar la colección: [Person.PhoneNumbers # 473] [SQL: ACTUALIZAR phone_numbers SET person_id = null DONDE person_id = @ p0]"}

InnerException:

{"No se puede insertar el valor NULL en la columna ''person_id'', tabla ''directory.dbo.phone_numbers''; la columna no permite valores nulos. La ACTUALIZACIÓN falla. / R / nLa declaración ha terminado."}

Mi configuración fluida es:

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

La clase padre es:

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

La clase infantil (Número de teléfono) es:

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

Mi código para eliminar a una persona es:

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

¿Qué estoy haciendo mal?


Funciona; Esto es lo que significa cada opción en cascada:

ninguno - no haga ninguna cascada, deje que los usuarios los manejen por sí mismos.

guardar-actualizar : cuando el objeto se guarda / actualiza, verifique las asociaciones y guarde / actualice cualquier objeto que lo requiera (incluido guardar / actualizar las asociaciones en un escenario de muchos a muchos).

eliminar : cuando se elimina el objeto, elimine todos los objetos de la asociación.

delete-huérfano : cuando se elimina el objeto, elimine todos los objetos de la asociación. Además de eso, cuando un objeto se elimina de la asociación y no se asocia con otro objeto (huérfano), también elimínelo.

Todo : cuando un objeto es guardar / actualizar / eliminar, verifique las asociaciones y guarde / actualizar / eliminar todos los objetos encontrados.

all-delete-huérfano : cuando un objeto se guarda / actualiza / elimina, verifique las asociaciones y guarde / actualice / elimine todos los objetos encontrados. Además de eso, cuando un objeto se elimina de la asociación y no se asocia con otro objeto (huérfano), también elimínelo.

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


No estoy seguro de configurar la parte Fluent, pero recientemente tuve el mismo problema con ActiveRecord.

Debe establecer su asociación, en el lado de la persona, como Inverse = true .

De mirar la documentación de Primeros pasos ...

Creo que es necesario establecer esto al definir su relación HasMany en persona. Debería verse algo como esto:

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