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

如何使用NHibernate将实体分布在多个表中?,nhibernate,Nhibernate,我有预先存在的表,使用一种开放模式。我有一个项目表,各种实体被分类为项目,然后在项目属性表中存储属性。单个实体类型可以在多个表中存储字段。我们使用视图公开实体。因此,大多数实体对应于一个视图,当我们插入/更新时,我们必须系统地更新表或使用存储过程 我试图确定NHibernate是否会比我们定制的存储库(遵循工厂模式)有所收获。现在,我发现让NHibernate处理这种数据库模式非常困难。在我看来,我们要么完全重构数据库以遵循NHibernate的约定,要么以某种方式完全重构实体 我在文档中没有看

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

我试图确定NHibernate是否会比我们定制的存储库(遵循工厂模式)有所收获。现在,我发现让NHibernate处理这种数据库模式非常困难。在我看来,我们要么完全重构数据库以遵循NHibernate的约定,要么以某种方式完全重构实体

我在文档中没有看到多少关于如何做到这一点的内容,除了一些非常简单的例子,这些例子涉及或多或少遵循NHibernate约定的数据库

下面是一个具有代表性的数据库图。我们将插曲作为一个实体,从Item、IP_插曲、IP_插曲广播信息、IP_Show等中提取信息,以构建它所需的所有字段


你提到惯例。这是一个流畅的NHibernate概念,是的,你所做的并不完全符合流畅的NHibernate现有的惯例。然而,这完全在NHibernate的能力范围内。NHibernate擅长映射到各种不同的数据库模式。不要拘泥于Fluent NHibernate希望你走的路。我不是说不要使用流利的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)
);
剧集
中的一行对应于
Show
中的零行或一行,而
广播
中的零行或一行。您可以在.NET中以几种不同的方式对这种类型的关系进行建模。以下是通过NHibernate为您提供的各种选项:

1.遗产 如果要对不发生更改的关系建模,请使用此选项。如果一集是一个节目,它总是一个节目。此外,这种建模意味着一个插曲不能既是一个节目又是一个广播。我不相信这是您想要的,但您可能会发现它在您的模型的其他地方很有用

有关更多信息,请参阅

2. <代码>一对一 这使您能够更好地控制哪些表实际包含与给定剧集相关联的行,因为您可以设置
spice.Broadcast=null
。对于给定的一集,同时拥有节目和广播信息也很好

有关更多信息,请参阅

3. <代码>加入 这是一种很好且简单的数据表示方法,但是您无法控制是否将on not行插入Show和Broadcast表中

有关更多信息,请参阅


既然您说过,“一个实体类型可能有存储在多个表中的字段”,在我看来,
join
应该能够处理当前建模的方式。

您能给出POCO层次结构的表示(如果有)吗。我指的是你正在使用的接口和类,其实并没有层次结构。我只是有一个平面对象层次结构。所以,这一集从几张桌子上抽出来;从几张桌子上拉出来的节目;事件等。虽然这一集不包含Show,但它确实包含Show中的一些字段,如Name、Guid(Show的_ItemGuid)等。这是可行的,但我需要更好地了解哪些数据在哪个表中。
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; }
}
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; }
}
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; }
}