NHibenate:有没有一种方法可以使用复合键创建一对多的双向关系?

时间:2019-07-09 13:56:01

标签: c# nhibernate

我正在尝试在NHibernate上的两个类上建立双向一对多关系,它们的复合键都重叠。 另一个困难是,我不能仅仅编辑SQL表以例如添加适当的ID。

这可能是一个简单的问题,但我在任何地方都找不到答案。

据我所知,我已经放弃了HasMany。但是我坚持使用HasOne。还尝试了参考。

public class Parent
{
    public string A { get; set; }
    public string B { get; set; }
    public string C { get; set; }
    public List<Child> Children { get; set; }
    public string Data { get; set; }
}
public class Child
{
    public string A { get; set; }
    public string B { get; set; }
    public string C { get; set; }
    public string D { get; set; }
    public Parent Parent { get; set; }
    public string Data { get; set; }
}

public class ParentMap : ClassMap<Parent>
{
    public ParentMap()
    {
        CompositeId()
            .KeyProperty(x => x.A)
            .KeyProperty(x => x.B)
            .KeyProperty(x => x.C);
        Map(x => x.Data);
        HasMany(x => x.Children)
                .KeyColumn("A")
                .KeyColumn("B")
                .KeyColumn("C");
    }
}
public class ChildMap : ClassMap<Child>
{
    public ChildMap()
    {
        CompositeId()
            .KeyProperty(x => x.A)
            .KeyProperty(x => x.B)
            .KeyProperty(x => x.C)
            .KeyProperty(x => x.D);
        Map(x => x.Data);
        HasOne(x => x.Parent);
        // also tried
        //References<Parent>(x => x.Parent)
                //.Columns("A", "B", "C");
    }
}

我现在得到的错误是: NHibernate.FKUnmatchingColumnsException:'外键(FK_3346D8AD:Child [C])必须与引用的主键(父[A,B,C])具有相同的列数”

2 个答案:

答案 0 :(得分:1)

对不起,我不熟悉nhibernate,但总的来说,关于您的Child.Parent属性映射-此处一对一(HasOne)映射不正确。一对一映射仅在两个实体的Id相同时才有效。因此,ChildParent都应该为[A,B,C]。

但是多对一映射(References)应该有效-您只需要将所有引用的列或属性标记为只读(您需要在hbm.xml中找到与insert="false" update="false"相当的语言)因为这些列已经是您ID映射的一部分。在hbm.xml中,映射如下所示:

<many-to-one name="Parent" insert="false" update="false" not-null="true">
    <column name="A"/>
    <column name="B"/>
    <column name="C"/>
</many-to-one>

因此,在流畅的休眠状态下,其外观应类似于:

References<Parent>(x => x.Parent).Columns("A", "B", "C")
//Not sure if it exists
.Readonly(); 
//Or something like this
.Insert(false).Update(false);

答案 1 :(得分:0)

问题是:

HasMany(x => x.Children)
    .KeyColumn("A")
    .KeyColumn("B")
    .KeyColumn("C");

应该是什么:

HasMany(x => x.Children)
    .KeyColumns.AddRange("A", "B", "C");