Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mapping to multiple tables with Fluent nHibernate

Here's my situation..
Suppose you have the following model entities, which represent single tables on their own:

Movies [ Movie_Id, Title, Rating, .. ]
Actors [ Actor_Id, FirstName, LastName, .. ]
Director [ Director_Id, FirstName, LastName, .. ]

And another entity/table called "Recommendations", which represents recommendations between users within a website. The idea is that a recommendation could be of any type, i.e. someone recommending an actor, or someone recommending a movie. Basically, the table should look something like this:

Recommendations [ Recommendation_Id, Object_Id, Object_Type, .. ]

And here's what i'm stuck into. How can I map these relationships in nHibernate with Fluent? I mean.. while mapping, I can't specify the Type (which table related to) 'cause that's determined on runtime, but I can't rely only on the Id 'cause by itself it cannot imply to which table belongs to.
For instance, imagine this record on Recommendations table:

Recommendation_Id--Object_Id--Object_Type
83001--4010123---"M"

Basically I'm storing a char identifier (in this case "M" stands for table "Movies") to know to which table Object_Id belongs to. I cannot just store Object_Id without Object_Type..

As final comments, I'd like to add that I've seen all the table-per-class, table-per-subclass, table-per-concrete-class examples, but I believe none of these fits in this situation, as Movies_Id, Actors_Id, Directors_Id, ... are all different between them, so is Recommendations_Id. I mean, there's no base class-child class inheritance here, they don't share Id's at all..

I hope I make myself clear. Thanks in advance.

like image 200
Matias Bello Avatar asked Jan 24 '12 15:01

Matias Bello


People also ask

What is the difference between NHibernate and fluent NHibernate?

Fluent NHibernate offers an alternative to NHibernate's standard XML mapping files. Rather than writing XML documents, you write mappings in strongly typed C# code. This allows for easy refactoring, improved readability and more concise code.

What is NHibernate mapping?

nhibernate Mappings Xml Mappings It is a syntax xml file which contains the metadata required for the object/relational mapping. The metadata includes declaration of persistent classes and the mapping of properties (to columns and foreign key relationships to other entities) to database tables.

Is NHibernate an ORM?

NHibernate is a popular, fast growing ORM with a helpful community of seasoned developers. Used in thousands of commercial and open source projects.


1 Answers

The NHibernate mapping you are looking for is <any/>. Here are a few resources to help you get up to speed with this NHibernate mapping feature:

  • Ayende's blog post
  • NHibernate documentation
  • Fluent NHibernate documentation

I believe the *.hbm.xml that you are shooting for is something like this:

<class name="Recommendation" table="Recommendations">
  <id name="Id">
    <column name="Recommendation_Id" />
    <generator class="native"/>
  </id>

  <any name="RecommendedObject" id-type="System.Int32" meta-type="System.String">
    <meta-value value="M" class="Movie"/>
    <meta-value value="A" class="Actor"/>
    <meta-value value="D" class="Director"/>
    <column name="Object_Type"/>
    <column name="Object_Id"/>
  </any>

  <!-- other stuff ... -->
</class>

You should be able to accomplish that with Fluent NHibernate like so in Recommendation's mapping:

ReferencesAny(x => x.RecommendedObject)
    .IdentityType<int>()
    .EntityTypeColumn("Object_Type")
    .EntityIdentifierColumn("Object_Id")
    .AddMetaValue<Movie>("M")
    .AddMetaValue<Actor>("A")
    .AddMetaValue<Director>("D");
like image 157
Daniel Schilling Avatar answered Sep 21 '22 19:09

Daniel Schilling