Tengo un problema con lo que debería ser un caso de uso de NHibernate bastante simple (creo).NHibernate establece la clave externa en la actualización secundaria en lugar de en la inserción inicial que viola la restricción no nula en la columna clave
Uno de mis padres clásico y una entidad secundaria, así:
public class Parent
{
public virtual int ParentId { get; set; }
public virtual string Name { get; set; }
public virtual IList<Child> Children { get; set; }
}
public class Child
{
public virtual int ChildId { get; set; }
public virtual Parent Parent { get; set; }
public virtual string Name { get; set; }
}
y las asignaciones de la siguiente manera:
public class ParentMap : ClassMap<Parent>
{
public ParentMap()
{
Id(x => x.ParentId).GeneratedBy.Native();
Map(x => x.Name);
HasMany(x => x.Children).KeyColumn("ParentId").Cascade.SaveUpdate();
}
}
public class ChildMap : ClassMap<Child>
{
public ChildMap()
{
Id(x => x.ChildId).GeneratedBy.Native();
Map(x => x.Name);
References(x => x.Parent).Column("ParentId").ReadOnly().Not.Nullable();
}
}
Por último, tengo unas pruebas sencillas:
[Test]
public void Test_save_family()
{
var parent = new Parent();
var child = new Child {Parent = parent};
parent.Children = new List<Child>{child};
SessionManager.WithSession(
session =>
{
session.Save(parent);
session.Flush();
});
}
La prueba falla con System.Data.SqlClient.SqlException: No se puede insertar el valor NULL en la columna 'ParentId'. Esto es correcto porque la columna no admite nulos, pero ¿por qué está insertando nulo?
Si quito la restricción nula, la obra ahorrar porque NHibernate primero inserta el padre, a continuación, inserta el niño, luego actualiza la columna de la parentid en el registro hijo como se muestra en esta salida:
NHibernate: INSERT INTO [Parent] (Name) VALUES (@p0); select SCOPE_IDENTITY();@p0 = NULL
NHibernate: INSERT INTO [Child] (Name) VALUES (@p0); select SCOPE_IDENTITY();@p0 = NULL
NHibernate: UPDATE [Child] SET ParentId = @p0 WHERE ChildId = @p1;@p0 = 2, @p1 = 1
Esto parece Es extraño para mí, ya que en casi todos los casos, las columnas de clave externa de este tipo se declaran no nulables y, por lo tanto, la clave externa se debe proporcionar en la inserción. Entonces, ¿por qué NHibernate no está configurando la clave externa en la inserción inicial de la fila secundaria y cómo corregir esto?
James, bien retirar el calificativo de sólo lectura() trabajó para conseguir la aprobación de prueba. Sin embargo, ahora estoy confundido sobre el significado de ReadOnly(). Según tengo entendido, ReadOnly() significa que NHibernate nunca actualizará la columna después de la inserción inicial, y que nunca asignará un valor a la inserción. –
ReadOnly() significa que el valor nunca se escribe en insertar o actualizar. Se usa principalmente para tablas de búsqueda y columnas calculadas. –
Hmm, lo sabía, ahora que lo mencionas. Creo que confundí ReadOnly() como un atributo de propiedad con ReadOnly como un atributo de entidad. Debe envejecer. :) ¡Gracias por la ayuda! –