4

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

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

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

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

图式

4

1 回答 1

2

你提到约定。这是一个 Fluent 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例如。对于给定的剧集,同时拥有 Show 和 Broadcast 信息也很好。

有关更多信息,请参阅...

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应该能够处理您当前建模事物的方式。

于 2013-08-16T19:15:26.640 回答