4

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

我有一个 Root 类、Middle 类和“底层”类。根类为“中间”作为子级,然后中间有“底部”作为子级。但是,在这个设计不佳的遗留数据库中,“底部”还引用了“根”。

根表

  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#实体

  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);
    }
}
4

1 回答 1

5

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

于 2012-10-22T12:12:11.973 回答