You mention conventions. That is a Fluent NHibernate concept, and yes, what you are doing is not exactly in line with Fluent NHibernate's existing conventions. However, it is well within NHibernate's capabilities. NHibernate excels at being able to be mapped to all sorts of different database schemas. Don't feel constrained to the way Fluent NHibernate wants you to go. I'm not saying don't use Fluent NHibernate. If you are consistent and reasonable in your database schema, you can write your own conventions to match.
To illustate NHibernate's flexibility, let's assume we have a table structure similar to this:
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)
);
One row in Episode corresponds to zero or one rows in Show and zero or one rows in Broadcast. You could model this type of relationship several different ways in .NET. Here are the various options available to you via NHibernate:
1. Inheritance
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; }
}
Use this when you want to model a relationship that does not change. If an Episode is a Show, it is always a Show. Also, this modeling would imply that an Episode cannot be both a Show and a Broadcast. I don't believe this is what you want, but you may find it useful elsewhere in your model.
For more info, see...
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; }
}
This gives you more control over which tables actually contain a row associated with a given Episode, because you can set episode.Broadcast = null for example. It's also fine to have both Show and Broadcast information for a given Episode.
For more info, see...
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; }
}
This is a nice and simple way to represent the data, but you do not get control over whether on not rows are inserted into the Show and Broadcast tables or not.
For more info, see...
Since you said, "A single entity type may have fields stored in multiple tables", it sounds to me like join should be able to handle the way you currently have things modeled.