无法将值NULL插入列 - 具有2个父项的NHibernate实体

时间:2012-10-21 22:39:09

标签: c# nhibernate fluent-nhibernate

{“无法将值NULL插入列'RootID',表'Legacy.dbo.Middle';列不允许空值.INSERT失败。\ r \ n语句已终止。”}

我有一个Root类,Middle类和'bottom'类。作为孩子的“中间”的根类,然后中间有“底部”作为孩子。但是,在这个设计较差的遗留数据库中,还有一个来自“底部”的“Root”的引用。

根表

  CREATE TABLE [dbo].[Root](
    [RootID] [int] IDENTITY(1,1) NOT NULL,
    [RootName] [varchar](max) NOT NULL,
 CONSTRAINT [PK_Root] PRIMARY KEY CLUSTERED 
(
    [RootID] 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].[Middle](
        [MiddleID] [int] IDENTITY(1,1) NOT NULL,
        [MiddleName] [varchar](max) NOT NULL,
        [RootID] [int] NOT NULL,
     CONSTRAINT [PK_Middle] PRIMARY KEY CLUSTERED 
    (
        [MiddleID] 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].[Bottom](
        [BottomID] [int] IDENTITY(1,1) NOT NULL,
        [BottomName] [varchar](max) NOT NULL,
        [MiddleID] [int] NOT NULL,
        [RootID] [int] NOT NULL,
     CONSTRAINT [PK_Bottom] PRIMARY KEY CLUSTERED 
    (
        [BottomID] 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].[Middle]  WITH CHECK ADD  CONSTRAINT [FK_Middle_Root] FOREIGN KEY([RootID])
    REFERENCES [dbo].[Root] ([RootID])
    GO

    ALTER TABLE [dbo].[Middle] CHECK CONSTRAINT [FK_Middle_Root]

    ALTER TABLE [dbo].[Bottom]  WITH CHECK ADD  CONSTRAINT [FK_Bottom_Middle] FOREIGN KEY([MiddleID])
    REFERENCES [dbo].[Middle] ([MiddleID])
    GO

    ALTER TABLE [dbo].[Bottom] CHECK CONSTRAINT [FK_Bottom_Middle]
    GO

ALTER TABLE [dbo].[Bottom]  WITH CHECK ADD  CONSTRAINT [FK_Bottom_Root] FOREIGN KEY([RootID])
REFERENCES [dbo].[Root] ([RootID])
GO

ALTER TABLE [dbo].[Bottom] CHECK CONSTRAINT [FK_Bottom_Root]

c#entities

  public class Root
    {
        public Root()
        {
            Middles = new SortedSet<Middle>();
        }

        public int RootID { get; set; }
        public string RootName { get; set; }
        public ISet<Middle> Middles { get; set; }
    }

    public class Middle
    {
        public Middle()
        {
            Bottoms = new SortedSet<Bottom>();
        }

        public int MiddleID { get; set; }
        public Root Root
        {
            get;
            set;
        }

        public string MiddleName { get; set; }
        public ISet<Bottom> Bottoms { get; set; }
    }

    public class Bottom
    {
        public int BottomID { get; set; }
        public Root Root { get; set; }
        public Middle Middle { get; set; }
        public string BottomName { get; set; }
    }

我通过FluentNHibernate使用以下映射,但我尝试了很多变化而无法让它以任何方式工作。

public class RootMap : IAutoMappingOverride<Root>
{
    public void Override(AutoMapping<Root> mapping)
    {
        mapping.Not.LazyLoad();
        mapping.Id(x => x.RootID);
        mapping.HasMany(x => x.Middles).KeyColumn("RootID").Cascade.AllDeleteOrphan().Inverse();
    }
}

public class MiddleMap : IAutoMappingOverride<Middle>
{
    public void Override(AutoMapping<Middle> mapping)
    {
        mapping.Not.LazyLoad();
        mapping.Id(x => x.MiddleID);
        mapping.References(x => x.Root);
        mapping.HasMany(x => x.Bottoms).KeyColumn("MiddleID").Cascade.AllDeleteOrphan();
    }
}

public class BottomMap : IAutoMappingOverride<Bottom>
{
    public void Override(AutoMapping<Bottom> mapping)
    {
        mapping.Not.LazyLoad();
        mapping.Id(x => x.BottomID);
        mapping.References(x => x.Root);
        mapping.References(x => x.Middle);
    }
}

1 个答案:

答案 0 :(得分:5)

您需要将关系的多值方面声明为“逆”。见6.4节的最后一段:http://nhibernate.info/doc/nh/en/index.html#collections-onetomany