首页 > 解决方案 > NHibernate 父表和子表在其组合中具有不同数量的键

问题描述

我在控制台应用程序中使用 NHibernate 映射有点挣扎。

这是摘要:

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,我最终得到了一个错误(完全有意义)

然后,我尝试使用复合 ID,其中 3 个键用于分发,2 个键用于发票。正如我相信你们中的许多人已经知道的那样,这也以错误告终,因为有两条记录分别使用 11 和 44 作为供应商和发票。

我的问题:有没有办法使用复合 ID(INVOICE 和 VENDOR)声明关系,并且仍然让子集合尊重/强制 3 键复合(INVOICE、VENDOR 和 NUM)的唯一性?

我已经尝试了几种组合键的排列,但无法弄清楚。也许它不是为此而设计的。任何帮助将非常感激!

标签: c#nhibernatefluent-nhibernate

解决方案


鉴于您在实体上有一个复合 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.
    }
}

我没有尝试此代码,这只是一个建议,以检查哪些对您有用。


推荐阅读