如何将NHibernate与实体分布在多个表中?

时间:2013-06-21 21:59:25

标签: nhibernate

我有一个预先存在的表,使用一种开放的模式。我有一个Item表,各种实体被归类为Items,然后将属性存储在Item属性表中。单个实体类型可以具有存储在多个表中的字段。我们使用视图公开实体。因此,大多数实体对应一个视图,然后当我们插入/更新时,我们必须系统地更新表或使用存储过程。

我正在尝试确定NHibernate是否会通过我们定制的存储库(遵循工厂模式)获得任何东西。现在,我发现让NHibernate处理这种数据库模式非常困难。我看待它的方式,我们要么必须完全重构我们的数据库以遵循NHibernate的约定,要么以某种方式完全重构或实体。

我没有在文档中看到有关如何执行此操作的内容,除了涉及数据库的最简单的示例,这些示例或多或少遵循NHibernate的约定。

这是一个有代表性的数据库图表。我们将Episode作为一个实体,从Item,IP_Episode,IP_EpisodeBroadcastInfo,IP_Show等中提取信息,以构建所需的所有字段。

schema

1 个答案:

答案 0 :(得分:1)

你提到了约定。这是一个流畅的NHibernate概念,是的,你所做的并不完全符合Fluent NHibernate的现有惯例。但是,它完全符合NHibernate的功能。 NHibernate擅长映射到各种不同的数据库模式。不要被Fluent NHibernate希望你去的方式所束缚。我不是说不要使用Fluent NHibernate。如果数据库模式中的一致且合理,则可以编写自己的约定来匹配。

为了说明NHibernate的灵活性,让我们假设我们有一个类似于此的表结构:

create table Episode (
    Id int not null primary key,
    NumberInSeries int null
);

create table Show (
    Episode_id int not null primary key,
    Title nvarchar(100) not null,
    foreign key (Episode_id) references Episode (Id)
);

create table Broadcast (
    Episode_id int not null primary key,
    InitialAirDate datetime not null,
    foreign key (Episode_id) references Episode (Id)
);

Episode中的一行对应Show中的零行或一行以及Broadcast中的零行或一行。您可以在.NET中以几种不同的方式为这种类型的关系建模。以下是NHibernate提供的各种选项:

1。继承

public class Episode
{
    public virtual int Id { get; set; }
    public virtual int? NumberInSeries { get; set; }
}

public class Show : Episode
{
    public virtual string Title { get; set; }
}

public class Broadcast : Episode
{
    public virtual DateTime InitialAirDate { get; set; }
}

如果要为不会更改的关系建模,请使用此选项。如果剧集是一个节目,它总是一个节目。此外,这种建模意味着剧集不能同时是节目和广播。我不相信这是你想要的,但你可能会发现它在你的模型的其他地方很有用。

有关详细信息,请参阅...

2。 one-to-one

public class Episode
{
    public virtual int Id { get; set; }
    public virtual int? NumberInSeries { get; set; }
    public virtual Show Show { get; set; }
    public virtual Broadcast Broadcast { get; set; }
}

public class Show
{
    public virtual Episode Episode { get; set; }
    public virtual string Title { get; set; }
}

public class Broadcast
{
    public virtual Episode Episode { get; set; }
    public virtual DateTime InitialAirDate { get; set; }
}

这使您可以更好地控制哪些表实际包含与给定剧集关联的行,因为您可以设置episode.Broadcast = null。对于给定的剧集,同时显示和播放信息也很好。

有关详细信息,请参阅...

3。 join

public class Episode
{
    // These properties come from the Episode table...
    public virtual int Id { get; set; }
    public virtual int? NumberInSeries { get; set; }

    // This one comes from the Show table.
    public virtual string Title { get; set; }

    // This one comes from the Broadcast table.
    public virtual DateTime InitialAirDate { get; set; }
}

这是一种表示数据的简单方法,但您无法控制是否将行插入到Show和Broadcast表中。

有关详细信息,请参阅...

既然你说过“单个实体类型可能在多个表中存储了字段”,我觉得join应该能够处理你当前建模的方式。