none
How to change the type of an object? RRS feed

  • Question

  • Hi,

     

    I'm quite new to all this, so apologies in advance if this is a dumb question!

     

    I've setup a project with an SQL database and I've used Visual Studio's built in designer to build an entity model (which it's stored in a nice dbml file for me!).

     

    I've created an entity type of 'Party', which acts as a base class with inherited classes of 'Individual' and 'Organisation'.  'Individual' then also acts as a base class for a further class called 'User'.  All of these are based on a single 'Party' table in the database.

     

    This all works fine - I can create Organisations, Individuals and Users.

     

    However, I can see at some point that I will want to take a person who is currently an 'Individual' and turn them into a 'User' (and vice-versa).  How would I go about doing this?  I effectively want to change the class of an existing entity - I guess?!

     

    Any help would be appreciated!

     

    Thanks,

    - Chris

    Friday, June 6, 2008 8:34 PM

Answers

  • Discriminator is the column value used to map an entity to a base\child class for a LINQ to SQL inheritance hierarchy. It is updatable till you don't map it to the primary key of the table (in which case it anyways has limited usage). So you should be able to do what you want.

    Friday, June 6, 2008 10:55 PM
  • Hi,

     

    Thanks for your reply.  I've tried changing the value of the discriminator field in my code but I get an exception thrown telling me that changing the value would cause the type of the object to change.  I can see why it wouldn't like this - but that is actually what I am trying to achieve!!

     

    Any ideas?

     

    Thanks,

    - Chris

    Saturday, June 7, 2008 8:35 AM
  • Hi Chris,

     

    I really think that you shouldn't do it this way. Remember that LINQ to SQL is on O/R mapper, it bridges the relational model and object model together. But the whole idea with O/RM is to think with objects and work with objects. The relational model shouldn't be bothering the programmers head.

     

    The change you are trying to do is not possible in object model (you cannot make a Party object to be a User object, unless it is a User already). So my advice is to do it the object-oriented way: create another object if this kind of change happens. Then delete the old one in the database and insert the new one.

     

    If you really want to avoid doing this for some reason, you could execute a direct SQL statement in LINQ to SQL and modify the discriminator column of the row that holds you object's information (UPDATE ...). But remember that this might generate runtime errors, because of the LINQ to SQLs identity management feature: you might need to create a new data context when you do such a change in some cases. Another drawback is that the code will depend on the mapping, so if you would want to change the discriminator codes for classes, your code could break. And of course there might be a problem when associations are involved: you might break the whole object model. Consider this scenario:

     

    A User class is associated with a Foo class 1 - 1. You change a type of on object form User to Organisation, which does not have an association with Foo class. Now, if you fetch the new Organisation from database, everything might be fine, but what if you would want to list all the Foos and their Users? Your Organisation will magically become a User, but they are in a different branch of the inheritance hierarchy. Plus, it might generate another set of runtime errors Smile.

     

    I hope I helped,

    Maciek

    Sunday, June 8, 2008 11:15 AM
  • In order to change the type of the object you need to copy the contents of the object to a new instance.  Create a new instance of the desired type, copy the contents of the original type into it (including the PK), then you can DeleteOnSubmit the original instance and InsertOnSubmit the new instance.
    Sunday, June 8, 2008 5:47 PM
    Moderator

All replies

  • Discriminator is the column value used to map an entity to a base\child class for a LINQ to SQL inheritance hierarchy. It is updatable till you don't map it to the primary key of the table (in which case it anyways has limited usage). So you should be able to do what you want.

    Friday, June 6, 2008 10:55 PM
  • Hi,

     

    Thanks for your reply.  I've tried changing the value of the discriminator field in my code but I get an exception thrown telling me that changing the value would cause the type of the object to change.  I can see why it wouldn't like this - but that is actually what I am trying to achieve!!

     

    Any ideas?

     

    Thanks,

    - Chris

    Saturday, June 7, 2008 8:35 AM
  • Hi Chris,

     

    I really think that you shouldn't do it this way. Remember that LINQ to SQL is on O/R mapper, it bridges the relational model and object model together. But the whole idea with O/RM is to think with objects and work with objects. The relational model shouldn't be bothering the programmers head.

     

    The change you are trying to do is not possible in object model (you cannot make a Party object to be a User object, unless it is a User already). So my advice is to do it the object-oriented way: create another object if this kind of change happens. Then delete the old one in the database and insert the new one.

     

    If you really want to avoid doing this for some reason, you could execute a direct SQL statement in LINQ to SQL and modify the discriminator column of the row that holds you object's information (UPDATE ...). But remember that this might generate runtime errors, because of the LINQ to SQLs identity management feature: you might need to create a new data context when you do such a change in some cases. Another drawback is that the code will depend on the mapping, so if you would want to change the discriminator codes for classes, your code could break. And of course there might be a problem when associations are involved: you might break the whole object model. Consider this scenario:

     

    A User class is associated with a Foo class 1 - 1. You change a type of on object form User to Organisation, which does not have an association with Foo class. Now, if you fetch the new Organisation from database, everything might be fine, but what if you would want to list all the Foos and their Users? Your Organisation will magically become a User, but they are in a different branch of the inheritance hierarchy. Plus, it might generate another set of runtime errors Smile.

     

    I hope I helped,

    Maciek

    Sunday, June 8, 2008 11:15 AM
  • In order to change the type of the object you need to copy the contents of the object to a new instance.  Create a new instance of the desired type, copy the contents of the original type into it (including the PK), then you can DeleteOnSubmit the original instance and InsertOnSubmit the new instance.
    Sunday, June 8, 2008 5:47 PM
    Moderator
  • Thanks to all for your help!

     

    I'm traditionally a relational database man - so it's taking a while to get my head around the object oriented way of doing things!!

     

    - Chris

    Sunday, June 8, 2008 8:31 PM