Mapear dos tablas en una sola entidad, con referencia a otra (Mapping by code)

91 views
Skip to first unread message

Juan José Montes de Oca Arbós

unread,
Jan 8, 2018, 2:43:10 PM1/8/18
to nhibernat...@googlegroups.com
Buenas grupo!!!

En un proyecto en el que estoy trabajando, necesito mapear 2 tablas para generar una sola entidad. No tengo mayores inconvenientes con eso (utilizo JOIN), pero una de esas tablas tiene una relación contra otra tabla (como una propiedad) y esa es la parte que no me doy cuenta como resolver.

Si no mapeo la entidad que es una propiedad (para que la infiera NH), el sistema me indica el siguiente error:

Missing column: TipoDocumentoId in Hospital.dbo.Medico

Si mapeo dicha entidad, el sistema me indica el siguiente error:

Could not determine type for: Domain.TipoDocumento, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null, for columns: NHibernate.Mapping.Column(TipoDocumentoId)


A nivel de base de datos, tengo una tabla que representa el Personal de un hospital, con sus datos básicos (Nombre, Nro de documento, Tipo de Documento, etc) y otra tabla que representa a los Médicos de dicho Hospital con sus datos destacados (Matricula, y PersonalId).

La entidad en C# que quiero representar es un médico, que tiene Nombre, Nro Documento, Tipo de Documento y Matricula. El problema es que Tipo de Documento es otra tabla, y no se como representarla en los mappings.

Tengo estas tablas:


y este diagrama de clases


El mapeo que tengo es este:

            Join("Personal", j =>
            {
                j.Key(k => k.Column("Id"));
                j.Property(o => o.Nombres, m => m.Type((IIdentifierType)TypeFactory.GetAnsiStringType(50)));
                j.Property(o => o.Apellidos, m => m.Type((IIdentifierType)TypeFactory.GetAnsiStringType(150)));
                j.Property(o => o.Sexo, m => { m.Column(a => a.SqlType("char")); });
                j.Property(o => o.NumeroDocumento, m => { m.Column("NumeroDocumento"); });
                j.Property(o => o.TipoDocumento, m =>
                {
                    m.Column(a => { a.Name("TipoDocumentoId"); a.SqlType("bigint"); });
                });

            });

Estoy medio perdido, pero no me doy cuenta como resolverlo, googleando y leyendo documentación no encontré ningún ejemplo con un caso como este.

Si elimino la propiedad TipoDocumento de la clase Medico, funciona bien (obviamente sin tener esa propiedad disponible, que la necesito).

¿Alguna punta por donde puedo encontrar la solución?


GRACIAS!!!


--
Juan José Montes de Oca Arbós.

Carlos Peix

unread,
Jan 9, 2018, 5:24:42 AM1/9/18
to nhibernate-hispano
Hola JJ,

No estoy respondiendo a tu pregunta. Disculpas!

Pregunto, porque estás modelando de esa manera? Por ejemplo, cómo representas en ese modelo una persona que, además de médico, es paciente? Probablemente estés obligado a repetir sus datos como persona.

Sugiero que mires ejemplos de modelar un rol.

--
--
Para escribir al Grupo, hágalo a esta dirección: NHibernate-Hispano@googlegroups.com
Para más, visite: http://groups.google.com/group/NHibernate-Hispano
---
Has recibido este mensaje porque estás suscrito al grupo "NHibernate-Hispano" de Grupos de Google.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a nhibernate-hispano+unsub...@googlegroups.com.
Para acceder a más opciones, visita https://groups.google.com/d/optout.

Juan José Montes de Oca Arbós

unread,
Jan 9, 2018, 7:23:20 AM1/9/18
to nhibernat...@googlegroups.com
Hola Carlos, los pacientes siguen un modelo diferente. Lo que tenemos en base de datos es el PERSONAL del Hospital, y, en otra tabla, los datos extra del médico (que es, hasta donde necesitamos, la Matricula del mismo). Así, lo que se pensó, es tener todo el personal en la tabla de personal (Medicos, Enfermeros, Administrativos, Contadores, etc) y si se necesitan datos extras para alguno de estos, se arma su correspondiente tabla con los datos extra.

Los datos y su estructura parten desde otro sistema, el sistema en el que estoy trabajando solo toma los datos y los usa de solo lectura, para crear nuevos datos...

Gracias!!

Saludos Y ÉXITOS!!


--
Juan José Montes de Oca Arbós.

===========================
Web personal: http://juanjose.montesdeocaarbos.com.ar/blog/

El 9 de enero de 2018, 7:24, Carlos Peix <carlo...@gmail.com> escribió:
Hola JJ,

No estoy respondiendo a tu pregunta. Disculpas!

Pregunto, porque estás modelando de esa manera? Por ejemplo, cómo representas en ese modelo una persona que, además de médico, es paciente? Probablemente estés obligado a repetir sus datos como persona.

Sugiero que mires ejemplos de modelar un rol.
Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a nhibernate-hispano+unsubscribe@googlegroups.com.

Para acceder a más opciones, visita https://groups.google.com/d/optout.

Carlos Peix

unread,
Jan 9, 2018, 8:49:48 PM1/9/18
to nhibernate-hispano
Hola JJ,

Verificaste el namespace del al clase TipoDocumento?

----------------------------------
Carlos Peix

Juan José Montes de Oca Arbós

unread,
Jan 10, 2018, 1:51:22 PM1/10/18
to nhibernat...@googlegroups.com
Hola Carlos, el namespace es el mismo que en Medico.

De hecho, también probé de mapear la clase Medico contra la tabla Personal, y el mapping funciona bien, devolviendo los objetos con sus Tipos de documento... lo que me lleva a pensar que es algo que tengo mal declarado en el mapping del Join.



--
Juan José Montes de Oca Arbós.

===========================
Web personal: http://juanjose.montesdeocaarbos.com.ar/blog/
El 9 de enero de 2018, 22:49, Carlos Peix <carlo...@gmail.com> escribió:
Hola JJ,

Verificaste el namespace del al clase TipoDocumento?

----------------------------------
Carlos Peix

Para cancelar la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a nhibernate-hispano+unsubscribe@googlegroups.com.

Para acceder a más opciones, visita https://groups.google.com/d/optout.

nelopa...@gmail.com

unread,
Jan 10, 2018, 9:12:39 PM1/10/18
to nhibernat...@googlegroups.com
Hola JJ, Carlos, grupo...

¿probaste de implementar los tipos de documentos como "well-known instance"?.. igual, si los datos son de otro sistema y solo los usas de lectura, quizás pensaría en armar una vista que haga el join correspondiente (left si querés todo el personal, inner si querés solo los médicos) y mapearía contra la vista como no mutable.

saludos
nelo

Juan José Montes de Oca Arbós

unread,
Jan 11, 2018, 6:13:16 AM1/11/18
to nhibernat...@googlegroups.com
Hola Nelo,
 lo de armar una vista fue lo que pensé si no podía resolverlo mediante mapping directo a las tablas, entiendo que se debería poder, y que si no lo estoy consiguiendo es por una falta de conocimiento de mi parte ¿verdad?

 No se me había ocurrido lo de "well-know instance" (no conocía el termino, aunque lo venimos usando en algún cliente). Aunque podría hacerlo, sigo con la duda sobre el mapeo de tablas mediante el Join... si puedo mapear Personal que tiene su propiedad TipoDocumento, y ese mapping funciona bien ¿que debería configurar para que Medico (que se obtiene de un join entre Medico y Personal) posea una propiedad que se relaciona contra otra tabla?




--
Juan José Montes de Oca Arbós.

===========================
Web personal: http://juanjose.montesdeocaarbos.com.ar/blog/

El 10 de enero de 2018, 23:12, nelopa...@gmail.com <nelopa...@gmail.com> escribió:
Hola JJ, Carlos, grupo...

¿probaste de implementar los tipos de documentos como "well-known instance"?.. igual, si los datos son de otro sistema y solo los usas de lectura, quizás pensaría en armar una vista que haga el join correspondiente (left si querés todo el personal, inner si querés solo los médicos) y mapearía contra la vista como no mutable.

saludos
nelo

Message has been deleted

Andrés Falcón

unread,
Feb 26, 2018, 12:08:41 AM2/26/18
to NHibernate-Hispano
Hola Juan

Te pido si podes poner el mapping de todas las clases que tenga relación con lo que querés hacer y de la estructura de las tablas correspondientes. Así podemos tener un panorama completo.

Saludos.

Juan José Montes de Oca Arbós

unread,
Mar 14, 2018, 3:05:07 PM3/14/18
to nhibernat...@googlegroups.com
Hola Andrés, las tablas son bastante simples. Antes de pegar el código comento un par de cosas:

* Como dato a resaltar, los médicos son Personal, y en la tabla Medico unicamente se guarda la matricula.
* Si en lugar de dos tablas, Personal y Medico fueran una sola (o una Vista que representa a una sola tabla), y yo no tengo que hacer el mapping mediante el Join, NH infiere la propiedad TipoDocumento del médico y la resuelve sin problemas.
* No hay una clase PERSONAL (si una tabla) porque entiendo que para resolver esto no se necesita.

//TABLAS (simplificadas)
TipoDocumento
    [Id] [bigint] IDENTITY(1,1) NOT NULL
    [Codigo] [varchar](20) NOT NULL
    [Descripcion] [varchar](50) NOT NULL

Personal
    [Id] [bigint] IDENTITY(1,1) NOT NULL,
    [Nombres] [varchar](50) NOT NULL,
    [Apellidos] [varchar](150) NOT NULL,
    [Sexo] [char](1) NOT NULL,
    [TipoDocumentoId] [bigint] NULL,
    [NumeroDocumento] [int] NOT NULL,

Medico
    [Id] [bigint] IDENTITY(1,1) NOT NULL,
    [PersonalId] [bigint] NOT NULL,
    [Matricula] [varchar](30) NULL,


//Mappings (simplificados)
    public class TipoDocumentoMapping : ClassMapping<TipoDocumento>
    {
        public TipoDocumentoMapping()
        {
            Id(x => x.Id, m => m.Generator(Generators.Identity));
            Property(o => o.Codigo, m => m.Type((IIdentifierType)TypeFactory.GetAnsiStringType(20)));
            Property(o => o.Descripcion, m => m.Type((IIdentifierType)TypeFactory.GetAnsiStringType(50)));
        }
    }

    public class MedicoMapping : ClassMapping<Medico>
    {
        public MedicoMapping()
        {
            //Esto es lo que está mal, no se como generar el Join si Médico posee la propiedad TipoDocumento que no sea de un tipo primitivo
            Id(x => x.Id, m => m.Generator(Generators.Identity));

            Join("Personal", j =>
            {
                j.Key(k => k.Column("Id"));
                j.Property(o => o.Nombres, m => m.Type((IIdentifierType)TypeFactory.GetAnsiStringType(50)));
                j.Property(o => o.Apellidos, m => m.Type((IIdentifierType)TypeFactory.GetAnsiStringType(150)));
                j.Property(o => o.Sexo, m => { m.Column(a => a.SqlType("char")); });
                j.Property(o => o.NumeroDocumento, m => { m.Column("NumeroDocumento"); });
            });

        }
    }


//Clases (Simplificadas):
    public class Medico : Entity
    {
        public virtual long Id { get; set; }

        //public virtual TipoDocumento TipoDocumento { get; protected set; } Si esta propiedad no está comentada, no sabe resolver el Join

        public virtual int NumeroDocumento { get; protected set; }

        public virtual char Sexo { get; protected set; }

        public virtual string Apellidos { get; protected set; }

        public virtual string Nombres { get; protected set; }

        public override string ToString()
        {
            return string.Format("{0} {1}", Apellidos.Trim(), Nombres.Trim()).Trim();
        }
    }

    public class TipoDocumento : Entity
    {
        public virtual long Id { get; set; }

        public virtual string Codigo { get; protected set; }

        public virtual string Descripcion { get; protected set; }
    }



Saludos Y ÉXITOS!!




--
Juan José Montes de Oca Arbós.

===========================
Web personal: http://juanjose.montesdeocaarbos.com.ar/blog/
Reply all
Reply to author
Forward
0 new messages