我在控制台应用程序中为NHibernate映射而苦苦挣扎。
这里是摘要:
这是一对多的关系。 PARENT_TABLE(一个)到CHILD_TABLE(许多)
PARENT_TABLE具有由两个键组成的复合键:供应商和发票
Id(x => x.Invoice).Column("INVOICE");
References(x => x.Distribution).Column("INVOICE");
Id(x => x.Invoice).Column("INVOICE");
HasOne(x => x.Invoice).ForeignKey("INVOICE").Cascade.Refresh();
当我浏览具有以下示例的某些数据时:
供应商发票编号
10 | 44 | 1
11 | 44 | 1
11 | 44 | 2
由于发票中的ID重复,我最终得到了一个错误(使您有充分的理解)
然后,我尝试使用3个ID用于分发,两个ID用于发票的复合ID。我敢肯定,你们中的许多人都知道,这也导致了错误,因为有两个记录分别使用11和44分别用于供应商和发票。
我的问题:是否有一种方法可以使用复合ID(INVOICE和VENDOR)声明关系,并且仍然使子集合尊重/加强3个关键复合键(INVOICE,VENDOR和NUM)的唯一性?
我已经尝试了几种组合键的排列方式,但是还没有弄清楚。也许它不是为此而设计的。任何帮助将不胜感激!
鉴于您在实体上具有复合ID定义,因此必须使用CompositeId
方法对其进行映射。在您的子实体中,您还必须定义父实体的关键列的引用,因为它是一个复合ID(这就是我个人不喜欢使用复合ID的原因)。
考虑您的模型:
public class ParentEntity
{
public virtual int Vendor { get; set; }
public virtual int Invoice { get; set; }
// other properties
}
public class ChildEntity
{
public virtual int Vendor { get; set; }
public virtual int Invoice { get; set; }
public virtual int Num { get; set; }
public virtual ParentEntity ParentEntity { get; set; }
}
您的映射可能是这样:
public class ParentEntityMap : ClassMap<ParentEntity>
{
public ParentEntityMap()
{
CompositeId()
.KeyProperty(x => x.Vendor, "VENDOR")
.KeyProperty(x => x.Invoice, "INVOICE");
// other mappings ...
}
}
public class ChildEntityMap : ClassMap<ChildEntity>
{
public ChildEntity()
{
CompositeId()
.KeyProperty(x => x.Vendor, "VENDOR")
.KeyProperty(x => x.Invoice, "INVOICE")
.KeyProperty(x => x.Num, "NUM");
References(x => x.ParentEntity)
.Columns("VENDOR", "INVOICE")
.ReadOnly(); // if you are mapping the same columns of compositeId here, define it as readOnly to avoid inserting data two times on the same columns.
}
}
我没有尝试过此代码,它只是建议您检查适合您的方法。