一般例子:
抽象映射类A. 抽象映射的类B:答: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
实际剥离示例:
BaseTemplate表:
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
MiddleTemplate表:
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
LastTemplate表:
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
LastTemplateInstance表:
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
}
答案 0 :(得分:0)
我看到你错过了BaseTemplateMap上的DiscriminateSubClassesOnColumn地图,以及MiddleTemplateMap和LastTemplateMap上的DiscriminatorValue地图。
一旦你让NHibernate知道如何识别基于描述符的类型,它应该加载正确的对象(即在你的情况下它是B类型),你的转换应该工作。
看看这个sample
答案 1 :(得分:0)
尝试访问BaseTemplateInstance.Template时出现问题。如果您在映射到NOT lazyLoad中设置此引用,则工作正常!
目前的理论是,在加载之前尝试从中访问属性会导致异常。确保它不是延迟加载的,意味着它将被加载,允许正确的转换,并且可以访问属性。