NHibernate Save试图在更新时清除子KeyColumn Id

时间:2014-05-16 13:41:49

标签: nhibernate fluent-nhibernate fluent-nhibernate-mapping

我正在尝试创建一个父对象,该对象在1对多关系中有多个子对象。我没有在子对象上引用Parent对象,而是将其keycolumn映射为字段。

当我第一次尝试保存此对象时,它按预期工作,没有任何问题(级联所有Id和子级)。当我尝试从数据库中获取对象时,更新它上面的一些属性并重新保存它,它会失败。我得到的实际错误消息是“无法删除集合”。

上面的错误是由于它试图将子对象上的“ParentId”字段设置为NULL(这违反了我在db中的FK约束)。如果我从数据库中删除此约束,最终结果就是我想要的;但是,我不希望它执行此更新(将父ID设置为null)并且我不确定它为什么。从我在SQL代码中可以看出它生成并发送到数据库,其他一切看起来都是正确的,如果它不适用于最后一个更新语句,它将全部工作。

显然,我的映射确实有问题,但我无法弄清楚是什么。我尝试添加Not.KeyUpdate(),但这简直使它根本不生成密钥。有没有人有任何想法我做错了什么?

先谢谢,我真的很感激!!!

请参阅下面的我的地图:

public class Parent
    {
        public Parent()
        {
            Children = new List<Child>();
        }

        public virtual Guid Id { get; set; }

        public virtual IList<Child> Children { get; set; }
    }

    public class Child
    {
        public virtual Guid Id { get; set; }

        public virtual Guid ParentId { get; set; }
    }

    public class ParentMap : ClassMap<Parent>
    {
        public ParentMap()
        {
            Table("Parent");
            Id(x => x.Id);
            HasMany(x => x.Children).KeyColumn("ParentId").Cascade.SaveUpdate().Not.LazyLoad();
        }
    }

    public class ChildMap : ClassMap<Child>
    {
        public ChildMap()
        {
            Table("Child");
            Id(x => x.Id);
            Map(x => x.ParentId);
        }
    }

1 个答案:

答案 0 :(得分:1)

这是因为 children 的集合未标记为inverse="true"

您可以做的是:I。从DB中删除约束。 NHiberante只需要(没有反向设置)做2个步骤。首先更新记录以打破关系,其次(由于级联)删除项目

II。更改映射和实体。像这样:

Child必须引用Parent

public class Child
{
    public virtual Guid Id { get; set; }

    public virtual Guid ParentId { get; set; }
    public virtual Parent Parent { get; set; }
}
然后

映射将是这样的:

public class ParentMap : ClassMap<Parent>
{
    public ParentMap()
    {
        Table("Parent");
        Id(x => x.Id);
        HasMany(x => x.Children)
            .KeyColumn("ParentId")
            .Cascade.SaveUpdate()
            .Not.LazyLoad()
            .Inverse() // here we do have the inverse setting
            ;
    }
}

public class ChildMap : ClassMap<Child>
{
    public ChildMap()
    {
        Table("Child");
        Id(x => x.Id);
        Map(x => x.ParentId).Not.Insert().Not.Update(); // this is readonly now
        References(x => x.Parent).Column("ParentId"); // just a Parent is writable
    }
}

现在,您必须始终在C#代码中正确设置关系。即如果将child添加到Parents集合中,则还应设置Parent引用

parent.Children.Add(child);
child.Parent = parent;

NHibernate现在只发出一个语句,从表中删除子项