你提到了约定。这是 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; }
}
当您想要建模不会改变的关系时,请使用此选项。如果一集是一场演出,那么它始终是一场演出。此外,这种建模意味着剧集不能同时是节目和广播。我不认为这是您想要的,但您可能会发现它在模型的其他地方很有用。
欲了解更多信息,请参阅...
- 关于继承映射的官方文档 http://nhforge.org/doc/nh/en/index.html#inheritance
- Ayende 关于继承映射的博客文章 http://ayende.com/blog/3941/nhibernate-mapping-inheritance
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
例如。拥有给定剧集的演出和广播信息也很好。
欲了解更多信息,请参阅...
- 官方文档one-to-one http://nhforge.org/doc/nh/en/index.html#mapping-declaration-onetoone
- Ayende 的博客文章one-to-one http://ayende.com/blog/3960/nhibernate-mapping-one-to-one
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 http://nhforge.org/doc/nh/en/index.html#mapping-declaration-join
- Ayende 的博客文章join http://ayende.com/blog/3961/nhibernate-mapping-join
既然您说“单个实体类型可能具有存储在多个表中的字段”,那么在我看来,join
应该能够处理您当前建模的方式。