问题:有没有办法根据上下文将单个外键映射到多个互斥表?
背景...
在我的具体示例中,我有以下域图,表示可以针对车辆 或 属性的保险索赔:
public enum InvolvedPartyContext
{
Vehicle = 1,
Property = 2
}
public class Claim
{
public virtual Guid Id { get; set; }
public virtual InvolvedPartyContext InvolvedPartyContext { get; set; }
public virtual Vehicle Vehicle { get; set; } // set if Context = Vehicle
public virtual Property Property { get; set; } // set if Context = Property
}
public class Vehicle { //... }
public class Property { //... }
SQL看起来像这样(注意单个外键 InvolvedPartyId ):
CREATE TABLE Claims (
Id uniqueidentifier NOT NULL,
InvolvedPartyContext int NOT NULL,
InvolvedPartyId uniqueidentifier NOT NULL
)
CREATE TABLE Vehicles (
Id uniqueidentifier NOT NULL,
Registration varchar(20) NOT NULL
)
CREATE TABLE Properties (
Id uniqueidentifier NOT NULL,
PostCode varchar(20) NOT NULL
)
声明的Fluent NHibernate映射文件:
public ClaimMap()
{
Id(x => x.Id);
Map(x => x.InvolvedPartyContext).CustomTypeIs(typeof(InvolvedPartyContext));
References(x => x.Vehicle, "InvolvedPartyId");
References(x => x.Property, "InvolvedPartyId");
}
由于相同的字段( InvolvedPartyId )被映射两次,因此抛出“此SqlParameterCollection具有Count {m}”异常的“无效索引{n}”。一个简单的解决方法是创建VehicleId和PropertyId字段,但在现实世界中还有更多的上下文,所以这不是很灵活。
答案 0 :(得分:2)
就个人而言,我不会选择你的设计。相反,我会分别创建Claim
类,VehicleClaim
和PropertyClaim
的子类。
public class VehicleClaim : Claim
{
public virtual Vehicle Vehicle { get; set; }
}
然后更改映射以使用InvolvedPartyContext
列作为鉴别器(NHibernate用于确定行所代表的类的列),并为每个子类创建子类映射。
public class ClaimMap : ClassMap<Claim>
{
public ClaimMap()
{
Id(x => x.Id);
DiscriminateSubClassesOnColumn("InvolvedPartyContext");
}
}
public class VehicleClaimMap : SubclassMap<VehicleClaim>
{
public VehicleClaimMap()
{
DiscriminatorValue(1);
References(x => x.Vehicle);
}
}
如果你确实想要运行你已经拥有的东西,你应该查看任何映射;关于它们没有很多文档,但您使用ReferencesAny
方法。