tags:

views:

30

answers:

2

Supposing the following entities :

public class AppUser
{
    public virtual int Id { get; set; }
    public virtual string Login { get; set; }
}

// Mapped as joined-subclass
public class Person : AppUser 
{
    public virtual int Age { get; set; }
}

If I create 1 AppUser, and save it like this

var user = new AppUser() { Login = "test" };
session.Save( user ); // let's say Id = 1

How can I cast/convert/"promote" it to a Person, keeping the same ID ?

Now, i'm stuck with a row in my AppUser table, with Id = N. How can I populate the Person table with the same Id ? I can't delete the AppUser and recreate it as a Person, as AppUser may be referenced by foreign keys.

I could issue a "manual" SQL INSERT, but it's kind of ugly...

This is definitively a NHibernate question. I understand that from an OOP point of view, this makes little sense, hence the absence of other tags than nhibernate.

+1  A: 

This has been discussed on SO before and I am quoting Jon Skeet for posterity:

No. A reference to a derived class must actually refer to an instance of the derived class (or null). Otherwise how would you expect it to behave?

For example:

object o = new object();
string s = (string) o;
int i = s.Length; // What can this sensibly do?

If you want to be able to convert an instance of the base type to the derived type, I suggest you write a method to create an appropriate derived type instance. Or look at your inheritance tree again and try to redesign so that you don't need to do this in the first place.

In Skeet's example, string's are objects and objects are not strings. So the "upcasting" would not work.

0A0D
+1  A: 

I don't believe nHibernate is going to be able to solve this problem for you. nHibernate is dealing with your data as an object and, especially with joined-subclass I don't believe there is anything built in that allows you to change the subclass type on the fly, or at least change the type and retain the original ID.

I think your best bet is to write a stored procedure that, given an ID and a NEW type, removes all entries from subclass tables and adds a new entry to the correct subclass table.

Once that proc runs, then reload the object in nHibernate (and make sure you have thrown away any cached data relating to it), it should now be of the correct type you want to work with, set its NEW properties and save it.

That way you have a relatively generic stored proc that just changes your subclass types, but you dont need to add all the crazy logic to handle various properties on your subclasses.

Max Schilling
That's what I thought... Looks like this time no overlooked nhibernate feature is here to help me !:)
mathieu
Well, if you look at what nHibernate is really doing, what you are talking about really breaks the model... with nHibernate, or ORM in general, you are mapping an object to a database table. When you are adding in a joined-subclass, you are already stretching that model a little bit, but it holds just because there is still that 1:1 relationship, now between a single object and multiple tables. Granted you can do what you are talking about with straight SQL, but the ORM abstraction here only holds so far...
Max Schilling
So, time to review some design ! Thank you.
mathieu