2011-04-18 20 views
9

Cuando uso NHibernate, si tengo una entidad que tiene una restricción única y que puede identificarse únicamente por esa restricción, ¿es mejor representar la restricción como una clave compuesta o tener un Id separado? campo y tienen una restricción única compuesta? He estado leyendo que se considera "malo" utilizar claves compuestas con NHibernate si puede y solo se debe usar cuando se trabaja con bases de datos heredadas.NHibernate Composite Key vs Composite Unique Constraint

Imagen de la configuración de la siguiente manera:

class Book 
{ 
    public virtual int Id { get; protected set; } 
    public virtual string Author { get; set; } 
    public virtual IList<BookEdition> Editions { get; set; } //HasMany (one to many) 
} 

class BookEdition 
{ 
    public virtual string Title { get; set; } 
    public virtual string Language { get; set; } 
    public virtual int Edition { get; set; } 
} 

Aquí tenemos una restricción para la BookEdition donde tiene una limitación en el lenguaje y edición, es decir, no puede haber dos ediciones del libro en el mismo idioma. Cualquier edición también puede identificarse de manera única mediante un número de edición y un idioma.

¿Qué enfoque se considera mejor en NHibernate? ¿Usa Language/Edition como Id compuesto o introduce una variable de Id para BookEdition y tiene una restricción compuesta única en su lugar?

Respuesta

9

La tecla de repetición (variable de Id. Adicional) es mejor, en general, no solo en NHibernate. El problema con las claves naturales (aquí: Idioma y Edición) es que tienen un significado "comercial". Las necesidades del negocio evolucionan a tiempo y seguramente tendrá que cambiar sus claves naturales en el futuro, lo que podría ser muy doloroso. Además, su SQL se une y donde las condiciones serán más complicadas.

Esto podría ser FNH mapeo de BookEdition con restricción única compuesta:

Id(x => x.Id); 
    Map(x => x.Title); 
    Map(x => x.Language).UniqueKey("MyCompositeUniqueConstraint"); 
    Map(x => x.Edition).UniqueKey("MyCompositeUniqueConstraint"); 

BTW. es una buena práctica no mostrar los valores clave supervivientes a los clientes. Tienden a asignarles un significado comercial y luego quieren cambiarlos también :).

+0

Este fue el mapeo en el que estaba pensando también. ¿Es una buena idea anular Equals/GetHashCode y usar la clave natural? En mi clase base, tengo un operador Equals que funciona en la propiedad Id, pero eso no es exacto para este caso. Tampoco es posible tener una clave natural compuesta usando "NaturalId()", creo. Tampoco tengo muy claro cuál es la diferencia entre una identificación natural y una restricción única, en términos de hibernación. –

+0

La restricción única de IMO (o clave) no juega ningún papel en las entrañas de NH. Es solo guía cómo crear db. esquema (crea una restricción en una tabla). Por otro lado, la clave primaria (compuesta, natural, superpuesta, no importa) es un concepto fundamental para el mapeo OR. Dice cómo encontrar de manera única una entidad en la tabla de la base de datos. –

+0

Hmm, parece que siempre es una buena idea anular Equals y, en consecuencia, GetHashCode, especialmente cuando se trata de carga lenta y proxies (http://devlicio.us/blogs/billy_mccafferty/archive/2007/04/25/using-equals- gethashcode-effective.aspx). Muy interesante, gracias por tu pregunta, parece que aún no sé nada sobre NH :). –

Cuestiones relacionadas