C# NHibernate复合密钥与复合唯一约束

C# NHibernate复合密钥与复合唯一约束,c#,.net,nhibernate,C#,.net,Nhibernate,使用NHibernate时,如果我有一个具有唯一约束的实体,并且该实体可以通过该约束唯一地标识,那么将约束表示为复合键还是使用单独的Id字段并具有复合唯一约束更好?我一直在读到,在NHibernate中使用复合键被认为是“不好的”,如果它可以帮助并且只应该在处理遗留数据库时使用 将设置映像如下所示: class Book { public virtual int Id { get; protected set; } public virtual string Author { get

使用NHibernate时,如果我有一个具有唯一约束的实体,并且该实体可以通过该约束唯一地标识,那么将约束表示为复合键还是使用单独的Id字段并具有复合唯一约束更好?我一直在读到,在NHibernate中使用复合键被认为是“不好的”,如果它可以帮助并且只应该在处理遗留数据库时使用

将设置映像如下所示:

class Book
{
   public virtual int Id { get; protected set; }
   public virtual string Author { get; set; }
   public virtual IList<BookEdition> Editions { get; set; } //HasMany (one to many)
}

class BookEdition
{
   public virtual string Title { get; set; }
   public virtual string Language { get; set; }
   public virtual int Edition { get; set; }
}
教材
{
公共虚拟整数Id{get;protected set;}
公共虚拟字符串作者{get;set;}
公共虚拟IList版本{get;set;}//HasMany(一对多)
}
班级图书编辑
{
公共虚拟字符串标题{get;set;}
公共虚拟字符串语言{get;set;}
公共虚拟整数版{get;set;}
}
这里我们对BookEdition有一个约束,它对语言和版本有一个约束,即不能有两个版本的书使用同一种语言。任何版本也可以通过版本号和语言进行唯一标识

NHibernate认为哪种方法更好?将语言/版本用作复合Id或为BookEdition引入Id变量,并使用复合唯一约束?

Surrorgate键(附加Id变量)通常比NHibernate更好。自然键(这里是语言和版本)的问题在于它们具有“业务”含义。业务需求会随着时间的推移而变化,将来你肯定要改变你的自然钥匙,这可能会非常痛苦。此外,SQL连接和where条件将更加复杂

这可能是具有复合唯一约束的BookEdition的FNH映射:

    Id(x => x.Id);
    Map(x => x.Title);
    Map(x => x.Language).UniqueKey("MyCompositeUniqueConstraint");
    Map(x => x.Edition).UniqueKey("MyCompositeUniqueConstraint");

顺便说一句,最好不要向客户展示surrorgate的关键价值观。他们倾向于赋予他们一些商业意义,然后他们也想改变它们:)。

这也是我所考虑的映射。使用natural键重写Equals/GetHashCode是个好主意吗?在我的基类中,我有一个Equals操作符,它处理Id属性,但在这种情况下并不准确。我认为使用“naturaid()”也不可能有复合自然键。我也不太清楚自然id和唯一约束之间的区别,用hibernate的术语来说..IMO唯一约束(或键)在NH内部不起任何作用。这是如何创建数据库的唯一指南。模式(在表上创建约束)。另一方面,主键(复合、自然、surrorgate-无所谓)是OR映射的基本概念。它说明了如何在数据库表中唯一地找到一个实体。嗯,似乎覆盖Equals和GetHashCode总是一个好主意,尤其是当涉及延迟加载和代理时()。非常有趣,谢谢你的提问,我似乎对NH一无所知:)。