9

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.

2
  • It should be noted that fluent nHibernate does not currently support many-to-any which is what I thought this would do. Unless I'm wrong, saving a recommendation when you update a movie won't happen seamlessly. Daniel's answer was closer to just about anything else I could find tho ;o) Commented Aug 1, 2013 at 20:47
  • If you want to map the other side of the any relationship, as in Movie.Recommendations, I believe you could do this with a one-to-many and a where="Object_Type='M'" attribute on the collection, which you can do with Fluent NHibernate. Commented Aug 28, 2013 at 2:20

1 Answer 1

14

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:

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");
Sign up to request clarification or add additional context in comments.

3 Comments

THANKS A LOT !!!! I've tested it and seems to work fine. Seriously, a million thanks Daniel! :=)
Could you please show an example how to query over the object RecommendedObject with filtering by Object_Id ?
@Christian, are you referring to stackoverflow.com/questions/21940396/…?

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.