2010-12-07 19 views
5

Tengo que modelar esta relación en NHibernate (simplifiqué un poco el código para mantener el tema): un empleado puede ser un administrador de cuentas (por lo tanto, es opcional):Asignación de una relación uno a uno con un esquema de base de datos incorrecto (brownfield)

tabla de empleados (Id, número, nombre) mesa EmployeeIsAccountManager (Número, MaxAllowedDiscount)

en lugar de tener una clave externa Id en la tabla EmployeeIsAccountManager señalando Empleado mesa, que tiene una columna de Número en el Empleado tabla que apunta a la columna Número en la tabla EmployeeIsAccountManager.

¿Cómo puedo asignar esto en NHibernate? He intentado usar el generador foráneo en la asignación de clase EmployeeIsAccountManager, pero si uso Number como valor generado en el extranjero, se asigna a la identificación del empleado, que es Id en lugar de Number. Modelé mi clase de usar composición:

public class Employee 
{ 
    public virtual int Id { get; set; } 
    public virtual short Number {get; set; } 
    public virtual string Name {get; set; } 
    public virtual AccountManager AccountManager { get; set; } 
} 

public class AccountManager 
{ 
    public virtual short Number { get; set; } /*needed because of ID only?*/ 
    public virtual decimal MaxAllowedDiscount { get; set } 
} 

He intentado un montón (uno-a-uno, muchos-a-uno, generador de divisas), pero no puedo averiguar si esto se puede hacer con NHibernate. BTW: Puedo cambiar las clases, mapeos, etc. pero NO PUEDO cambiar la estructura de la tabla debido a su estado de brownfield (aplicación antigua con más de 2 millones de líneas de código, casi 1000 formas).

¡Se agradece cualquier ayuda, gracias! Ted

+1

Busque el atributo de asignación de propiedad de ref ... – JulianM

Respuesta

0

Su pregunta me hace pensar en la herencia de clases, puede asignar su clase AccountManager como una subclase de Employee y luego podrá hacer lo que quiera hacer, probé un mapeo para usted pero como usted mesas diseñado de esa manera no resuelve sus necesidades, porque hay dos puntos que hay que notar en su asignación:

  1. la propiedad número en la tabla empleado debe ser un tipo único de clave extranjera al administrador de cuentas con el fin de ser utilizados como una clave externa, pero aún así no funciona porque NHibernate, cuando intente insertar un nuevo administrador de cuenta insertará un registro en la tabla de personas y luego asignará la identificación de la persona a la columna numérica de Accou ntManager y el break que necesitas.
  2. Mapear esa relación como muchos a uno no funciona por el mismo motivo. La propiedad Number de AccountManager es la clave principal? ¿es único? NHibernate no puede funcionar sin claves primarias, por lo que con el fin de hacer que la relación con el trabajo que tiene que especificar el Propety Número de AccountManager como una columna de Id

La última opción que viene en mi mente es el uso de una propiedad en el Clase de empleado asignada a la tabla AccountManager con una fórmula donde puede especificar una selección personalizada para obtener el valor que necesita Supongo que la propiedad MaxAllowedDiscount, pero esto también tiene alguna limitación, cuando mapea una propiedad con fórmula, esta propiedad no se puede insertar ni actualizado

Espero que esto ayude lat me konw si hay preguntas.

+0

he añadido un campo redundante adicional para el esquema de la base para que pudiera asignar este como debería . el campo en sí mismo es administrado por desencadenantes en la base de datos. – TedOnTheNet

0
public class Employee 
{ 
    public virtual short Number 
    { 
     get { return (AccountManager == null) ? 0 : AccountManager.Number; } 
     set 
     { 
      if (AccountManager == null) 
       AccountManager = new AccountManager(); 
      AccountManager.Number = value; 
     } 
    } 
    public virtual AccountManager AccountManager { get; set; } 
} 

o con GeneratedBy.Assinged()

public class Employee 
{ 
    public Employee() 
    { 
     AccountManager = new AccountManager(); 
    } 

    public virtual AccountManager AccountManager 
    { 
     get; 
     set { value.Parent = this; _accountManager = value; } 
    } 

    public class AccountManager 
    { 
     Internal protected virtual Employee Parent { get; set; } 

     protected virtual short Number { get { return Parent.Number; } set { } } /*needed because of ID only?*/ 
     public virtual decimal MaxAllowedDiscount { get; set } 
    } 
} 
Cuestiones relacionadas