C# 如何在nhibernate中使用逐类表的层次结构策略来管理多级类层次结构?
我正试图用NHibernate中的“每个类的表层次结构”策略在一个表中实现我的对象层次结构。我的NHibernate映射有一个错误,可以用一个简单的例子很容易地重现。错误是:C# 如何在nhibernate中使用逐类表的层次结构策略来管理多级类层次结构?,c#,nhibernate,nhibernate-mapping,C#,Nhibernate,Nhibernate Mapping,我正试图用NHibernate中的“每个类的表层次结构”策略在一个表中实现我的对象层次结构。我的NHibernate映射有一个错误,可以用一个简单的例子很容易地重现。错误是: System.NotSupportedException: Attempting to parse a null value into an sql string (column:activity0_.Type). at NHibernate.SqlCommand.InFragment.ToFragmentString()
System.NotSupportedException: Attempting to parse a null value into an sql string (column:activity0_.Type).
at NHibernate.SqlCommand.InFragment.ToFragmentString() in InFragment.cs: line 109
at NHibernate.Persister.Entity.SingleTableEntityPersister.DiscriminatorFilterFragment(String alias) in SingleTableEntityPersister.cs: line 551
我可以用以下域类来重现这一点:
public interface IActivity
{
Guid Id { get; set; }
}
public abstract class Activity : IActivity
{
public DateTime StartTime { get; set; }
public Guid Id { get; set; }
}
public class Running : Activity
{
public string Where { get; set; }
}
public class Talking : Activity
{
public string ToWhom { get; set; }
}
以及以下XML映射:
<?xml version="1.0" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
assembly="NHibernateTesting"
namespace="NHibernateTesting" >
<class name="IActivity"
lazy="false"
table="Activity"
discriminator-value="0"
abstract="true">
<id name="Id">
<generator class="guid" />
</id>
<discriminator column="Type" type="Int16" />
<subclass name="Activity"
discriminator-value="1"
abstract="true"
lazy="false">
<property name="StartTime" />
</subclass>
<subclass name="Running"
discriminator-value="2"
lazy="false"
extends="Activity">
<property name="Where" />
</subclass>
<subclass name="Talking"
discriminator-value="3"
lazy="false"
extends="Activity">
<property name="ToWhom" />
</subclass>
</class>
</hibernate-mapping>
有人知道我做错了什么吗?每个类一个AIK表意味着每个类在DB中有一个表,从父表到继承表有1-1个FK。那就不需要鉴别器了。 您也不需要映射IActivity(除非您希望您的会话直接针对它工作;然后需要进行一些调整)
无论如何,我强烈建议您浏览一下FluentNHibernate,它使映射变得超级简单,并且有非常有用的默认值来映射80%的对象,几乎没有任何代码我对c#和NHibernate不太熟悉,但是您确定映射中的
活动
应该设置为抽象=“true”
?看起来活动类不是抽象的
运行
和交谈
不应位于活动
内,否则启动时间将不会保存。对吧?
<subclass name="Activity"
...
<subclass name="Running"
...
</subclass>
<subclass name="Talking"
...
</subclass>
...
</subclass>
如果我正确解析了代码。当hit抛出此错误时,您试图做什么
您是否已经尝试在hibernate配置中启用这些功能以检查发生了什么
<property name="show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.use_sql_comments">true</property>
true
真的
真的
我指的是每个类层次结构的表,它有一个用于整个类层次结构的表。我确实看过Fluent NHibernate,但我正在学习它,因此我发现XML(以及相关手册)要容易得多。我还有一个复杂的对象模型,我必须处理一些不正常的东西。我想说,如果你还没有咨询NH用户组(nhusers@googlegroups),你最好的选择是咨询NH用户组。他们对NH的使用非常有帮助,tipsI不会切换到Fluent,因为他们不是NH的官方部分,甚至不是捐款包。当NH发展起来的时候,Fluent将会过时。@Stefan-我不同意。从Hibernate的历史来看,映射API不会在一夜之间发生剧烈的变化。BFluentNH由NH的大量用户开发。可以肯定的是,他们会将其与NH的任何开发计划保持一致。即使不是,它也是OSS,所以如果NH引入了突破性的更改,您可以随时使用它。即使您不想这样做,即使映射API发生了巨大的变化,您也可以将当前的fluent映射导出到hbm(它是一个单行程序),并继续使用xml路由。失去Fluent赋予您的超能力是一个错误,我认为,这是正确的答案:您需要嵌套子类元素。如果子类被移动到一个单独的映射文件中,则可以使用inherits属性。问题不在于类没有被声明为抽象类(尽管捕获良好),而在于子类没有被嵌套。谢谢你的帮助。这件事困扰了我好几天。
<property name="show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.use_sql_comments">true</property>