C# Fluent NHibernate,多个抽象基类继承不加载中间基类

C# Fluent NHibernate,多个抽象基类继承不加载中间基类,c#,nhibernate,fluent-nhibernate,nhibernate-mapping,subclass,C#,Nhibernate,Fluent Nhibernate,Nhibernate Mapping,Subclass,一般示例: 抽象映射类A。 抽象映射类B:A.B具有int类型的属性或任何您想要的属性。 映射类C:A 抽象映射类D具有类型a的属性。 映射的类E:D具有类型B的属性 将E保存到数据库中。检索它并尝试从E访问B.int。 抛出InvalidCastException:无法将类型为“AProxy”的对象强制转换为类型为“B” 使用FluentNhibernate:1.3.0 Nhibernate:3.2.0.4 实际精简示例: 基本模板表: USE [DB] GO SET ANSI_NULLS

一般示例:

抽象映射类A。 抽象映射类B:A.B具有int类型的属性或任何您想要的属性。 映射类C:A

抽象映射类D具有类型a的属性。 映射的类E:D具有类型B的属性

将E保存到数据库中。检索它并尝试从E访问B.int。 抛出InvalidCastException:无法将类型为“AProxy”的对象强制转换为类型为“B”

使用FluentNhibernate:1.3.0 Nhibernate:3.2.0.4

实际精简示例:

基本模板表:

USE [DB]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [temp].[BaseTemplate](
    [ID] [int] IDENTITY(1,1) NOT NULL,
 CONSTRAINT [PK_BaseTemplate] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
USE [DB]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [temp].[MiddleTemplate](
    [ID] [int] NOT NULL,
    [MiddleTemplateProperty] [int] NULL,
 CONSTRAINT [PK_MiddleTemplate] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [temp].[MiddleTemplate]  WITH CHECK ADD  CONSTRAINT [FK_MiddleTemplate_BaseTemplate] FOREIGN KEY([ID])
REFERENCES [temp].[BaseTemplate] ([ID])
GO

ALTER TABLE [temp].[MiddleTemplate] CHECK CONSTRAINT [FK_MiddleTemplate_BaseTemplate]
GO
USE [DB]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [temp].[LastTemplate](
    [ID] [int] NOT NULL,
    [LastTemplateProperty] [int] NULL,
 CONSTRAINT [PK_LastTemplate] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [temp].[LastTemplate]  WITH CHECK ADD  CONSTRAINT [FK_LastTemplate_BaseTemplate] FOREIGN KEY([ID])
REFERENCES [temp].[BaseTemplate] ([ID])
GO

ALTER TABLE [temp].[LastTemplate] CHECK CONSTRAINT [FK_LastTemplate_BaseTemplate]
GO
中间模板表:

USE [DB]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [temp].[BaseTemplate](
    [ID] [int] IDENTITY(1,1) NOT NULL,
 CONSTRAINT [PK_BaseTemplate] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
USE [DB]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [temp].[MiddleTemplate](
    [ID] [int] NOT NULL,
    [MiddleTemplateProperty] [int] NULL,
 CONSTRAINT [PK_MiddleTemplate] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [temp].[MiddleTemplate]  WITH CHECK ADD  CONSTRAINT [FK_MiddleTemplate_BaseTemplate] FOREIGN KEY([ID])
REFERENCES [temp].[BaseTemplate] ([ID])
GO

ALTER TABLE [temp].[MiddleTemplate] CHECK CONSTRAINT [FK_MiddleTemplate_BaseTemplate]
GO
USE [DB]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [temp].[LastTemplate](
    [ID] [int] NOT NULL,
    [LastTemplateProperty] [int] NULL,
 CONSTRAINT [PK_LastTemplate] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [temp].[LastTemplate]  WITH CHECK ADD  CONSTRAINT [FK_LastTemplate_BaseTemplate] FOREIGN KEY([ID])
REFERENCES [temp].[BaseTemplate] ([ID])
GO

ALTER TABLE [temp].[LastTemplate] CHECK CONSTRAINT [FK_LastTemplate_BaseTemplate]
GO
LastTemplate表:

USE [DB]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [temp].[BaseTemplate](
    [ID] [int] IDENTITY(1,1) NOT NULL,
 CONSTRAINT [PK_BaseTemplate] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
USE [DB]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [temp].[MiddleTemplate](
    [ID] [int] NOT NULL,
    [MiddleTemplateProperty] [int] NULL,
 CONSTRAINT [PK_MiddleTemplate] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [temp].[MiddleTemplate]  WITH CHECK ADD  CONSTRAINT [FK_MiddleTemplate_BaseTemplate] FOREIGN KEY([ID])
REFERENCES [temp].[BaseTemplate] ([ID])
GO

ALTER TABLE [temp].[MiddleTemplate] CHECK CONSTRAINT [FK_MiddleTemplate_BaseTemplate]
GO
USE [DB]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [temp].[LastTemplate](
    [ID] [int] NOT NULL,
    [LastTemplateProperty] [int] NULL,
 CONSTRAINT [PK_LastTemplate] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [temp].[LastTemplate]  WITH CHECK ADD  CONSTRAINT [FK_LastTemplate_BaseTemplate] FOREIGN KEY([ID])
REFERENCES [temp].[BaseTemplate] ([ID])
GO

ALTER TABLE [temp].[LastTemplate] CHECK CONSTRAINT [FK_LastTemplate_BaseTemplate]
GO
BaseTemplateInstance表:

USE [DB]
GO


SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [temp].[BaseTemplateInstance](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [TemplateID] [int] NOT NULL,
 CONSTRAINT [PK_BaseTemplateInstance] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [temp].[BaseTemplateInstance]  WITH CHECK ADD  CONSTRAINT [FK_BaseTemplateInstance_BaseTemplate] FOREIGN KEY([TemplateID])
REFERENCES [temp].[BaseTemplate] ([ID])
GO

ALTER TABLE [temp].[BaseTemplateInstance] CHECK CONSTRAINT [FK_BaseTemplateInstance_BaseTemplate]
GO
USE [DB]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [temp].[LastTemplateInstance](
    [ID] [int] NOT NULL,
 CONSTRAINT [PK_LastTemplateInstance] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [temp].[LastTemplateInstance]  WITH CHECK ADD  CONSTRAINT [FK_LastTemplateInstance_BaseTemplateInstance] FOREIGN KEY([ID])
REFERENCES [temp].[BaseTemplateInstance] ([ID])
GO

ALTER TABLE [temp].[LastTemplateInstance] CHECK CONSTRAINT [FK_LastTemplateInstance_BaseTemplateInstance]
GO
LastTemplateInstance表:

USE [DB]
GO


SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [temp].[BaseTemplateInstance](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [TemplateID] [int] NOT NULL,
 CONSTRAINT [PK_BaseTemplateInstance] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [temp].[BaseTemplateInstance]  WITH CHECK ADD  CONSTRAINT [FK_BaseTemplateInstance_BaseTemplate] FOREIGN KEY([TemplateID])
REFERENCES [temp].[BaseTemplate] ([ID])
GO

ALTER TABLE [temp].[BaseTemplateInstance] CHECK CONSTRAINT [FK_BaseTemplateInstance_BaseTemplate]
GO
USE [DB]
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [temp].[LastTemplateInstance](
    [ID] [int] NOT NULL,
 CONSTRAINT [PK_LastTemplateInstance] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [temp].[LastTemplateInstance]  WITH CHECK ADD  CONSTRAINT [FK_LastTemplateInstance_BaseTemplateInstance] FOREIGN KEY([ID])
REFERENCES [temp].[BaseTemplateInstance] ([ID])
GO

ALTER TABLE [temp].[LastTemplateInstance] CHECK CONSTRAINT [FK_LastTemplateInstance_BaseTemplateInstance]
GO
课程:

public abstract class BaseTemplate

public abstract class MiddleTemplate : BaseTemplate
    {
        public virtual int MiddleTemplateProperty { get; set; }
    }

public class LastTemplate : MiddleTemplate
    {
        public virtual int LastTemplateProperty { get; set; }
    }

public abstract class BaseTemplateInstance
    {
        public virtual BaseTemplate Template { get; set; }

        protected BaseTemplateInstance() {}
        protected BaseTemplateInstance(BaseTemplate template) : this()
        {
            Template = template;
        }
    }

public class LastTemplateInstance : BaseTemplateInstance
    {
        protected LastTemplateInstance() {}

        public LastTemplateInstance(LastTemplate template)
            :base(template) {}

        public virtual int MiddleTemplateProperty { get { return ((MiddleTemplate) Template).MiddleTemplateProperty; } }
    }
映射:

public class BaseTemplateMap : ClassMap<BaseTemplate>
    {
        public BaseTemplateMap()
        {
            Table("temp.BaseTemplate");

            // Unique Identifier
            Id(x => x.Id, "ID")
                .GeneratedBy.Identity();
        }
    }

 public class MiddleTemplateMap : SubclassMap<MiddleTemplate>
    {
        public MiddleTemplateMap()
        {
            Table("temp.MiddleTemplate");

            KeyColumn("ID");

            Map(x => x.MiddleTemplateProperty)
                .Nullable();
        }
    }


public class LastTemplateMap : SubclassMap<LastTemplate>
    {
        public LastTemplateMap()
        {
            Table("temp.LastTemplate");

            KeyColumn("ID");

            Map(x => x.LastTemplateProperty)
                .Nullable();
        }
    }

public class BaseTemplateInstanceMap : ClassMap<BaseTemplateInstance>
    {
        public BaseTemplateInstanceMap()
        {
            Table("temp.BaseTemplateInstance");

            // Unique Identifier
            Id(x => x.Id, "Id")
                .GeneratedBy.Identity();

            References(x => x.Template, "TemplateID")
                .Not.Nullable();
        }
    }

public class LastTemplateInstanceMap : SubclassMap<LastTemplateInstance>
    {
        public LastTemplateInstanceMap()
        {
            Table("temp.LastTemplateInstance");

            // Unique Identifier
            KeyColumn("ID");
        }
    }
测试示例:

[TestFixture]
    internal class TempFileTests
    {
        #region Members

        private LastTemplate _entity;
        private MappingsRepository _repository;

            #endregion // Members

        #region SetUp

        [TestFixtureSetUp]
        public void SetUpFixture()
        {
            _repository = MappingsRepository.GetInstance();
        }

        [SetUp]
        public void SetUp()
        {
            _entity = new LastTemplate();
        }

        #endregion // SetUp

        #region Tests

        [Test]
        public void LastTemplateInstanceMappingsTest()
        {
            var lastTemplateInstance = new LastTemplateInstance(_entity);
            _repository.Save(_entity);

            lastTemplateInstance = new PersistenceSpecification<LastTemplateInstance>(_repository.CurrentSession)
                .VerifyTheMappings(lastTemplateInstance);

            var middleProperty = lastTemplateInstance.MiddleTemplateProperty;
        }

        #endregion // Tests

        #region TearDown

        [TearDown]
        public void TearDown()
        {
            if (_entity != null && !_entity.IsNew())
                _repository.Delete(_entity);
        }

        [TestFixtureTearDown]
        public void TearDownFixture()
        {
            _repository.Dispose();
            _repository = null;
        }

        #endregion // TearDown
    }

我发现您缺少BaseTemplateMap上的DiscriminateSubClassesOnColumn映射,以及MiddleTemplateMap和LastTemplateMap上的DiscriminatorValue映射

一旦您让NHibernate知道如何根据描述符识别类型,它应该加载正确的对象,即在您的情况下,它是B类型,您的转换应该可以工作


看看这个

尝试访问BaseTemplateInstance.Template时会出现问题。如果在映射中将此引用设置为NOT lazyLoad,则效果很好


当前的理论是,在加载属性之前尝试从中访问属性会导致异常。确保它不是延迟加载的,这意味着它将被加载,允许正确的强制转换,并且可以访问属性。

LastTemplateInstance在哪里。正在为模板分配值?LastTemplate是MiddleTemplate的类型。在LastTemplateInstance的构造函数中,我们传入一个LastTemplate,您应该能够将其强制转换为MiddleTemplate以获得MiddleTemplateProperty。因此,在该上下文中不使用鉴别器。只有在每个层次结构使用一个表时才需要鉴别器。OP正在使用多个表。