使用NHibernate进行复合键/ Id映射

时间:2010-08-09 10:32:41

标签: nhibernate fluent-nhibernate nhibernate-mapping composite-key composite-id

我的数据库中有以下表格:

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 个答案:

答案 0 :(得分:8)

你应该做NHibernate告诉你的事情。 AnnouncementRead应覆盖EqualsGetHashCode方法。它们应基于属于主键的字段

答案 1 :(得分:1)

  1. 当实现equals时,你应该使用instanceof 来允许与子类进行比较。如果Hibernate延迟加载一对一或多对一关系,那么您将拥有该类的代理而不是普通类。代理是子类。比较班级名称会失败 更技术上:您应该遵循Liskows替换原则并忽略对称性。
  2. 下一个陷阱是使用 name.equals(that.name)而不是 name.equals(that.getName())。如果是代理,第一个将失败。
  3. http://www.laliluna.de/jpa-hibernate-guide/ch06s06.html