我在SO和google上看了很多关于nhibernate / fluent-nhibernate中的子类映射的问题,并没有设法找到与我有同样问题的人。我遵循了fluent-nhibernate wiki(http://wiki.fluentnhibernate.org/Fluent_mapping#Subclasses)的基本指令,但这没有帮助。
我有一个名为Operation的基本实体 - 它有一个与之关联的基表,然后我有子表UnpaidCheque,Refund等 - 每个子表的主键是一个外键,OperationId( PK)来自Operation表。
当我创建持久性规范并尝试验证我的映射时,它尝试将所有列保存到Operation表,而不是保存到Operation表,然后将Unpaid Check的特定列保存到UnpaidCheque表。
错误是:
could not insert: [UnpaidCheque][SQL: INSERT INTO Account.Operation (PaymentId, Amount, UnpaidOn, UnpaidByUserId, OperationType) VALUES (?, ?, ?, ?, 'U'); select SCOPE_IDENTITY()]
----> System.Data.SqlClient.SqlException : Invalid column name 'UnpaidOn'.
Invalid column name 'UnpaidByUserId'.
正如您所看到的,它正在尝试在UnpaidByUserId和UnpaidOn列中保存值,这些列是子表/类的成员而不是基础。
从好的方面来说,它试图在“操作类型”列中插入“U”的事实向我表明它似乎正在为类类型设置正确的描述符值。我已经指定了operationtype的唯一地方是在类映射中的DiscriminatorValue()调用中,我没有在其他地方明确地设置它。
类层次结构如下:
public class Operation
{
public virtual long OperationId { get; set; }
public virtual string OperationType { get; set; }
public virtual long? PaymentId { get; set; }
public virtual decimal Amount { get; set; }
}
public class UnpaidCheque : Operation
{
public virtual DateTime UnpaidOn { get; set; }
public virtual long UnpaidByUserId { get; set; }
}
类映射是:
public class OperationMap : ClassMap<Operation>
{
public OperationMap()
{
Schema("Account");
Table("Operation");
LazyLoad();
Id(_ => _.OperationId).Column("OperationId").GeneratedBy.Identity();
Map(_ => _.PaymentId).Column("PaymentId").Nullable();
Map(_ => _.Amount).Column("Amount").Not.Nullable();
DiscriminateSubClassesOnColumn("OperationType");
}
}
public class UnpaidChequeMap : SubclassMap<UnpaidCheque>
{
public UnpaidChequeMap()
{
Schema("Account");
Table("UnpaidCheque");
LazyLoad();
DiscriminatorValue("U");
KeyColumn("OperationId");
Map(_ => _.UnpaidOn).Column("UnpaidOn").Not.Nullable();
Map(_ => _.UnpaidByUserId).Column("UnpaidByUserId").Not.Nullable();
}
}
除了在子类映射中添加KeyColumn()之外,我看不到任何与示例不同的内容,但是我也得到了相同的错误消息。任何人都可以对我错过的内容有所了解,或者我想要实现的目标是否得到了nhibernate的支持?据我所知,它应该是。
提前致谢!
答案 0 :(得分:2)
要使用带有鉴别器的table-per-subclass,可以使用以下方法:
public class UnpaidChequeMap : SubclassMap<UnpaidCheque>
{
public UnpaidChequeMap()
{
Schema("Account");
DiscriminatorValue("U");
Join("UnpaidCheque", j =>
{
j.KeyColumn("OperationId");
j.Map(_ => _.UnpaidOn).Column("UnpaidOn").Not.Nullable();
j.Map(_ => _.UnpaidByUserId).Column("UnpaidByUserId").Not.Nullable();
}
}
}
答案 1 :(得分:1)
我们找到了解决方案:
描述符仅适用于所有子类存储在数据库中的同一个表中的映射。
删除行:
DiscriminateSubClassesOnColumn("OperationType");
来自父映射和
DiscriminatorValue("U");
从子映射,随后从数据库中删除列解决了问题。