在NHibernate中获取每个子类的表对象



我遇到了一个名为ScheduledJobs的DB表,它有大量列和一个具有相同大量属性的匹配C#对象。我对它的设计并不满意,我想用每个子类的表策略来分解它。代替

public class ScheduledJobs
{
    public int ID { get; set; } // always needed
    public int JobTypeID { get; set; } // always needed to distinguish A from B
    public int Foo { get; set; } // needed by Job A
    public int Bar { get; set; } // needed by Job B
}

我有

public abstract class ScheduledJob
{
    public int ID { get; set; }
    public ScheduledJobType JobType { get; set; }
}
public class ScheduledJobA : ScheduledJob
{
    public int Foo { get; set; }
}
public class ScheduledJobB : ScheduledJob
{
    public int Bar { get; set; }
}

我重写了NHibernate.hbm.xml文件(抱歉,没有Fluent)以使用:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    <class name="ScheduledJob" table="ScheduledJobs" abstract="true" lazy="false">
        <id name="ID" column="ID" type="Int32" unsaved-value="0">
            <generator class="identity" />
        </id>
        <many-to-one name="ScheduledJobType" column="JobTypeID" class="ScheduledJobType" />
        <joined-subclass name="ScheduledJobA" table="ScheduledJobsA" lazy="false">
            <key column="JobID" />
            <property name="Foo" type="Int32" />
        </joined-subclass>
        <joined-subclass name="ScheduledJobB" table="ScheduledJobsB" lazy="false">
            <key column="JobID" />
            <property name="Bar" type="Int32" />
        </joined-subclass>
    </class>
</hibernate-mapping>

太棒了!我的问题是,我不知道如何明智地获取子类作业。一张大桌子的好处是不必担心类型或铸造:

ScheduledJob job = Repository.ScheduledJob.Get(id);

在我的设置中,我有相同的ID(这应该足够了;它仍然是唯一的),但类型对我来说是未知的:我必须获取抽象作业,检查JobTypeID,找到相关的C#子类,并在该子类下重新绘制它。

如果我需要的话,我可以引入JobTypeID。我仍然需要将该ID与关联的作业子类表配对。

简而言之,我需要能够让我从NHibernate收到的ScheduledJob对象成为正确的子类,而我的干预尽可能少。在这里使用鉴别器的能力会很好,但官方文件说不允许这样做。这种设计让我觉得我从根本上误解了什么;请随意为我指明正确的方向。

谢谢!

在我的设置中,我有相同的ID(这应该足够了;它仍然唯一),但类型对我来说是未知的:我必须提取摘要job,检查JobTypeID,找到相关的C#子类,然后重新蚀刻它在那个子类下。

实际上,您既不必检查JobTypeID,也不必再次获取它。这就是NHibernate的工作:在初始获取时,它将确定适当的派生类型,并自动为您实例化此类型的对象。

如果在提取对象后需要查询类型,可以使用C#类型检查和强制转换:

ScheduledJob job = Repository.ScheduledJob.Get(id);
if (job is ScheduledJobA)
{
      ScheduledJobA jobA = (ScheduledJobA)jobA;
      ProcessJobA(jobA);
}
else if (job is ScheduledJobB)
{
      ScheduledJobB jobB = (ScheduledJobB)jobB;
      ProcessJobB(jobB);
}

最新更新