Mapeo Compuesto de Clave/Id con NHibernate
fluent-nhibernate nhibernate-mapping (2)
- Cuando implemente iguales, debe usar instanceof para permitir la comparación con subclases. Si Hibernate lazy carga una relación uno a uno o muchos a uno, tendrá un proxy para la clase en lugar de la clase simple. Un proxy es una subclase. La comparación de los nombres de clase fallaría.
Más técnicamente: debe seguir el principio de sustitución de Liskows e ignorar la simetría. - El siguiente escollo es usar algo como name.equals (that.name) en lugar de name.equals (that.getName ()) . El primero fallará, si eso es un proxy.
Tengo las siguientes tablas en mi base de datos:
Announcements:
- AnnouncementID (PK)
- Title
AnouncementsRead (composite PK on AnnouncementID and UserID):
- AnnouncementID (PK)
- UserID (PK)
- DateRead
Users:
- UserID (PK)
- UserName
Por lo general, asigno "AnnouncementsRead" utilizando una relación de muchos a muchos, pero esta tabla también tiene un campo adicional "DateRead".
Hasta ahora he definido las siguientes entidades:
public class Announcement
{
public virtual int AnnouncementID { get; set; }
public virtual string Title { get; set; }
public virtual IList<AnnouncementRead> AnnouncementsRead { get; private set; }
public Announcement()
{
AnnouncementsRead = new List<AnnouncementRead>();
}
}
public class AnnouncementRead
{
public virtual Announcement Announcement { get; set; }
public virtual User User { get; set; }
public virtual DateTime DateRead { get; set; }
}
public class User
{
public virtual int UserID { get; set; }
public virtual string UserName { get; set; }
public virtual IList<AnnouncementRead> AnnouncementsRead { get; private set; }
public User()
{
AnnouncementsRead = new List<AnnouncementRead>();
}
}
Con los siguientes mapeos:
public class AnnouncementMap : ClassMap<Announcement>
{
public AnnouncementMap()
{
Table("Announcements");
Id(x => x.AnnouncementID);
Map(x => x.Title);
HasMany(x => x.AnnouncementsRead)
.Cascade.All();
}
}
public class AnnouncementReadMap : ClassMap<AnnouncementRead>
{
public AnnouncementReadMap()
{
Table("AnnouncementsRead");
CompositeId()
.KeyReference(x => x.Announcement, "AnnouncementID")
.KeyReference(x => x.User, "UserID");
Map(x => x.DateRead);
}
}
public class UserMap : ClassMap<User>
{
public UserMap()
{
Table("Users");
Id(x => x.UserID);
Map(x => x.UserName);
HasMany(x => x.AnnouncementsRead)
.Cascade.All();
}
}
Sin embargo cuando ejecuto esto recibo el siguiente error:
"composite-id class must override Equals(): Entities.AnnouncementRead"
Apreciaría si alguien pudiera apuntarme en la dirección correcta. Gracias
Debes hacer justo lo que NHiberante te está diciendo. AnnouncementRead debe anular los métodos Equals
y GetHashCode
. Deben estar basados en campos que son parte de la clave primaria