4

I have pre-existing tables, using a kind of open schema. I have an Item table, and various entities are classified as Items, and then have properties stored in Item property tables. A single entity type may have fields stored in multiple tables. We expose entities with views. So, most entities correspond to a view, and then when we insert/update we have to systematically update the tables or use stored procedures.

I'm trying to determine if NHibernate will gain us anything over our custom-built repositories (which follow a factory pattern). Right now, I'm seeing great difficulty in getting NHibernate to deal with this kind of database schema. The way I see it, we'd either have to completely refactor our database to follow NHibernate's conventions, or completely refactor or entities somehow.

I'm not seeing much in the documentation about how to do this, except for the very simplest of examples that involve databases that more or less follow NHibernate's conventions.

Here's a representative database diagram. We have Episode as an entity that pulls info from Item, IP_Episode, IP_EpisodeBroadcastInfo, IP_Show, etc. to build all the fields that it needs.

schema

3
  • Can you give a representation of the POCO hierarchy (if any?). I mean interfaces, classes you're using. Commented Jun 22, 2013 at 5:54
  • Well, there isn't a hierarchy, per se. I just have a flat object hierarchy. So, Episode, which pulls from several tables; Show, which pulls from several tables; Event, etc. Episode does not contain a Show, though it does include some fields from Show such as Name, Guid (the Show's _ItemGuid), etc. Commented Jun 24, 2013 at 15:49
  • It is doable, but I would need a better idea of which data is in which table. Commented Aug 12, 2013 at 13:17

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.