流畅的NHibernate一对一,双向HasOne不保存孩子

时间:2015-05-04 15:50:24

标签: fluent-nhibernate

我在使用流利的nhibernate时遇到一对一的关系时遇到了问题。我已经阅读了很多帖子,看起来首选方法是共享主键方法,其中父级和子级具有相同的主键值,子PK也是父级的FK。

父类和子类都引用另一个(双向HasOne),并且子节点被配置为从父节点获取它的键值。

我相信我已经正确设置了它,但是当我创建一个新的Parent时,附加一个新的Child然后尝试保存它,父节点正确保存并且关键值在子对象上更新,但是子节点不是实际上已保存到数据库中。

以下是课程和地图:

public class Parent
{
    public virtual int ParentID { get; set; }
    public virtual string Name { get; set; }

    public virtual Child Child { get; set; }

    public virtual void Add(Child child)
    {
        child.Parent = this;
        Child = child;
    }
}

public class Child
{
    public virtual int ParentID { get; set; }
    public virtual string Name { get; set; }

    public virtual Parent Parent { get; set; }
}

public class ParentMap : ClassMap<Parent>
{
    public ParentMap()
    {
        Id(x => x.ParentID).GeneratedBy.Identity();
        Map(x => x.Name);

        HasOne(x => x.Child).Cascade.All();
    }
}

public class ChildMap : ClassMap<Child>
{
    public ChildMap()
    {
        Id(x => x.ParentID).GeneratedBy.Foreign("Parent");
        Map(x => x.Name);

        HasOne(x => x.Parent).Constrained().ForeignKey();
    }
}

这是NHibernate创建的模式(为简洁起见删除了一些GO):

CREATE TABLE [dbo].[Parent](
    [ParentID] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](255) NULL,
PRIMARY KEY CLUSTERED 
(
    [ParentID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]


CREATE TABLE [dbo].[Child](
    [ParentID] [int] NOT NULL,
    [Name] [nvarchar](255) NULL,
PRIMARY KEY CLUSTERED 
(
    [ParentID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
ALTER TABLE [dbo].[Child]  WITH CHECK ADD  CONSTRAINT [FK_ChildToParent] FOREIGN KEY([ParentID])
REFERENCES [dbo].[Parent] ([ParentID])
ALTER TABLE [dbo].[Child] CHECK CONSTRAINT [FK_ChildToParent]

所以它似乎创建了我期望的架构。但是我无法让孩子保存:

var parent = new Parent() { Name = "Parent_1" };
parent.Add(new Child { Name = "Child_1" });
session.Save(parent);

如上所述,这将正确保存父级并使用父级的值更新Child对象上的ParentID属性,但Child实际上并未保存到DB中,并且不会生成错误。

知道我做错了吗?

1 个答案:

答案 0 :(得分:1)

没关系。我觉得我好笨。映射是正确的,但是您必须在事务中包含Save以保留子对象,这在我的测试应用程序中没有。一旦我添加了交易,它就按预期工作了。