Composito Chiave/Id Mappatura con NHibernate

Ho le seguenti tabelle nel database:

Announcements:
- AnnouncementID (PK)
- Title

AnouncementsRead (composite PK on AnnouncementID and UserID):
- AnnouncementID (PK)
- UserID (PK)
- DateRead

Users:
- UserID (PK)
- UserName

Di solito vorrei sulla mappa il “AnnouncementsRead” che utilizza molti-a-molti rapporto, ma questo tavolo ha anche un ulteriore “DateRead campo”.

Finora ho definito i seguenti enti:

    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 i seguenti mapping:

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();
    }
}

Tuttavia, quando ho eseguito questo ho visualizzato il seguente messaggio di errore:

"composite-id class must override Equals(): Entities.AnnouncementRead"

Sarei grato se qualcuno potesse mi punto nella giusta direzione. Grazie

InformationsquelleAutor nfplee | 2010-08-09



2 Replies
  1. 8

    Si dovrebbe fare proprio quello che NHibernate sta dicendo. AnnouncementRead dovrebbe ignorare Equals e GetHashCode metodi. Esse devono essere basate su campi che fanno parte della chiave primaria

  2. 1
    1. Quando implementazione di equals si dovrebbe utilizzare instanceof per il confronto con le sottoclassi. Se Hibernate pigro carichi uno a uno o a più di una relazione, si avrà un proxy per la classe invece di pianura classe. Un proxy è una sottoclasse. Confrontando i nomi di classe fallirebbe.

      Più tecnicamente: Si consiglia di seguire le Liskows Principio di Sostituzione e di ignorare symmetricity.
    2. La prossima trappola è di utilizzare qualcosa come nome.equals(che.nome) invece di nome.equals(che.getName()). Il primo avrà esito negativo, se è un proxy.

    http://www.laliluna.de/jpa-hibernate-guide/ch06s06.html

    • La domanda si riferisce a C# e NHibernate, non Hibernate e Java. Non c’è nessuna tale cosa instanceof, nessun problema come .name-vs-.getName. Mentre la vostra risposta è, in generale, OK e una persona con esperienza sia in C# e Java in grado di “porta i concetti” attraverso il linguaggio/piattaforma di confine. Tuttavia, non ci sono molte di queste persone, e che rende la tua risposta difficilmente utilizzabile.

Lascia un commento