Составное отображение ключей / идентификаторов с помощью NHibernate - PullRequest
18 голосов
/ 09 августа 2010

В моей базе данных есть следующие таблицы:

Announcements:
- AnnouncementID (PK)
- Title

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

Users:
- UserID (PK)
- UserName

Обычно я сопоставляю «AnnouncementsRead», используя отношение «многие ко многим», но в этой таблице также есть дополнительное поле «DateRead».

До сих пор я определил следующие сущности:

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

Со следующими сопоставлениями:

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

Однако при выполнении этого я получаю следующую ошибку:

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

Буду признателен, если кто-нибудь укажет мне правильное направление.Спасибо

Ответы [ 2 ]

8 голосов
/ 09 августа 2010

Вы должны делать только то, что говорит вам NHibernate.AnnouncementRead должен переопределить Equals и GetHashCode методы.Они должны основываться на полях, которые являются частью первичного ключа

1 голос
/ 18 января 2013
  1. При реализации equals вы должны использовать instanceof , чтобы разрешить сравнение с подклассами.Если Hibernate lazy загружает отношение один к одному или много к одному, у вас будет простой прокси-класс для класса.Прокси-это подкласс.Сравнение имен классов не удастся.
    Более технически: вы должны следовать принципу подстановки Лискова и игнорировать симметрию.
  2. Следующая ловушка использует что-то вроде name.equals (that.name) вместо name.equals (that.getName ()) .Первый не удастся, если это прокси.

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

...