NHibernate复合键与复合唯一约束

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

将设置映像如下:

class Book { public virtual int Id { get; protected set; } public virtual string Author { get; set; } public virtual IList 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; } } 

在这里,我们对BookEdition有一个约束,它对语言和版本有一个约束,即在同一种语言中不能有两本版本的书。 任何版本也可以通过版本号和语言进行唯一标识。

在NHibernate中哪种方法被认为更好? 使用Language / Edition作为复合Id或为BookEdition引入Id变量并改为使用复合唯一约束?

Surrorgate键(附加Id变量)通常不仅在NHibernate中更好。 自然键(这里:语言和版本)的问题在于它们具有“商业”含义。 业务需求会随着时间的推移而发展,您将来必须改变自然键,这可能会非常痛苦。 此外,您的SQL连接以及条件将更复杂。

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

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

顺便说一句。 优秀的做法是不向客户显示关键值。 他们倾向于为他们分配一些商业意义,然后他们也希望改变它们:)。