当使用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; }
}
这里我们对BookEdition有一个约束,它对语言和版本有一个约束,即不能用同一种语言有两个版本的书。任何版本也可以通过版本号和语言进行唯一标识。
在NHibernate中哪种方法被认为更好?将Language / Edition用作复合ID或为BookEdition引入Id变量并改为使用复合唯一约束?
答案 0 :(得分:9)
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");
顺便说一下。优良做法是不向客户显示关键值。他们倾向于为他们分配一些商业意义,然后他们也希望改变它们:)。