Inheritance Question

Posts   
 
    
jflegere
User
Posts: 33
Joined: 22-Jul-2005
# Posted on: 07-May-2008 22:07:41   

I am new to using inheritance and have a question that follows along the same lines as in the thread http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=12915 with one difference that is not discussed there.

I have a supertype called Contact and two subtypes; Prospect and Client. My question concerns when a Prospect changes (hopefully) to a Client. In this case the entity is not both a Prospect and a Client as with some of the examples discussed (Student -> Teacher, etc.). Rather, when the Prospect becomes a Client, the Prospect ceases to exist.

The question then is, how do I change a Prospect into a Client? I'm pretty sure that the record in the Prospect table (with the correct foreign key) would need to be deleted, but how would the new record get created in the Client table? Would it happen automatically when I do something like:


ClientEntity client = new ClientEntity(old Prospect's ID)


or will that throw an error because the record doesn't exist in that table?

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 08-May-2008 05:09:24   

In my opinion, you should:

  1. Copy the needed info from Prospect into a new Client. You could assign the same Id as that prospect will be deleted.
  2. Delete Prospect (this will delete the implicit Contact record).
  3. Save the new Client (this will create implicitly a new Contact record).
David Elizondo | LLBLGen Support Team
luciusism
User
Posts: 119
Joined: 02-Jun-2007
# Posted on: 09-May-2008 20:03:07   

Unless your ID field is set to auto increment!

I had a similar type question just now that Walaa responded to, and it looks like if ids are auto-generated, then the solution is a kludge. Update database directly and have LL reload the entity as the new type.

I'd be interested in how others handle this. I'd think it a common enough use case.

Thanks,

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 10-May-2008 03:12:34   

IMHO, that would be a no-desirable design. The supertype should contain the identity PK, no the subtype. http://llblgen.com/TinyForum/Messages.aspx?ThreadID=11614

David Elizondo | LLBLGen Support Team
jflegere
User
Posts: 33
Joined: 22-Jul-2005
# Posted on: 10-May-2008 15:41:02   

I have "solved" this using two different methods. The first re-uses the supertype record (Contact) and the second creates a new supertype record. Both methods work as written because all of the columns in the Client (subtype) table are nullable. If this is not your case, you will need to collect any required Client-specifc information prior to converting the Prospect to a Client.

Method 1


int ID = Prospect.ID;

DataAccessAdapter adapter = new DataAccessAdapter();

try {
    ActionProcedures.Usp_ConvertProspectToClient(ID);
}

catch {
    throw;
}

finally {
    adapter.Dispose();
}

return new ClientService().GetClient(ID);

The stored procedure uses the ID parameter to insert a record into the Client table and delete a record from the Prospect table (inside a transaction, of course). The GetClient method of my ClientService simply reads the new Client using the same ID.

Method 2


// Create a new client
ClientEntity client = new ClientEntity();

// Copy the prospect's supertype information to the new client
_copyProspectInformationToClient(Prospect, client);

DataAccessAdapter adapter = new DataAccessAdapter();

adapter.StartTransaction(IsolationLevel.Serializable, "ConvertProspectToClient");

try {
     // Create the new client
    adapter.SaveEntity(client, true, true);

    // Delete the prospect
    adapter.DeleteEntity(Prospect);

    adapter.Commit();
}
catch {
    adapter.Rollback();

    throw;
}
finally {
    adapter.Dispose();
}

return client;


private void _copyProspectInformationToClient(ProspectEntity prospect, ClientEntity client) {
    foreach (IEntityField2 field in prospect.Fields) {
        // Copy only the information from the prospect's supertype
        if (field.ContainingObjectName == "ContactEntity" &&
            field.Name != "ID") {

            client.Fields[field.Name].CurrentValue = field.DbValue;
        }
    }
}


The code in _copyProspectInformationToClient() uses the field's ContainingObjectName property to determine which properties from the Prospect are in the supertype (ContactEntity) and copies those values to the Client.

The result of both methods is the same except that in Method 1 the supertype record remains the same whereas in Method 2 a new supertype record is created and the old is deleted so the ID is different.