Inheritance field mapping dumb question :)

Posts   
 
    
uranows
User
Posts: 6
Joined: 20-Jan-2006
# Posted on: 23-Jan-2006 19:59:08   

Hi,

I think this is a dumb question, but I really did'nt find the answer here yet simple_smile .

I have a CompanyCar (with general fields) and a specialized FamilyCar (with some particular fields) entity (a sub-type in the LLBLGen), then in someplace of the workflow a method receives the CompanyCar and need to create a specialized FamilyCar. But, at this step in the FamilyCar sql table there is no data yet, the step is to create it.

What's the best way to create a sub-type instance? I've tried the following:

public void StartFamilyCarWorkflow(CompanyCarEntity companyCar)
{
     FamilyCarEntity familyCar = new FamilyCarEntity(companyCar.carId);
     ...
}

and

public void StartFamilyCarWorkflow(CompanyCarEntity companyCar)
{
     FamilyCarEntity familyCar = (FamilyCarEntity)CompanyCarEntity.FetchPolymorphic(null,companyCar.carId, null);
     ...
}

But with both code de familyCar instance does not come with the companyCar fields filled. I should do it manual, like:

familyCar.Color = companyCar.Color;
familyCar.Type = familyCar.Type;
...
...

Or there is a best way to do it? Or it should be filled and I'm doing something wrong?

Thanks

bclubb
User
Posts: 934
Joined: 12-Feb-2004
# Posted on: 24-Jan-2006 02:47:34   

It's not a dumb question at all. It sounds like you are wanting to have a CompanyCar that should change to a FamilyCar. Like if you have an employee type and a manager type. When that employee is promoted you would think that you just make him a manger type and your good, but that's not really how it works. I may be misunderstanding you a bit but take a look at this thread and see if the answer makes sense in your scenario http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=4778&HighLight=1. You will most likely need to make a new family car entity and manually set the CompanyCar fields when it is created.

uranows
User
Posts: 6
Joined: 20-Jan-2006
# Posted on: 24-Jan-2006 06:02:46   

I understand what you said, but in this case, dont make sense create a new FamilyCar (with other ID) while some fundamental fields are on the CompanyCarEntity.

If I really can't do that, here comes my suggestion for next versions. Create some helper method that map the parent class fields to the child class. Then I use this method and save the child class.

Thanks anyway.

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 24-Jan-2006 06:41:14   

What you want to do is purely a Relational functionality and should not be implemented as inheritance.

Thus it should be implemented as a 'has a' relation rather than 'is a' relation.

With FamilyCar referencing CompanyCar. (FK-PK) So you will be able to add a Family Car that points out to a Company Car.

uranows
User
Posts: 6
Joined: 20-Jan-2006
# Posted on: 24-Jan-2006 15:20:40   

But using a standard relationship I still need to map the fields manually. Cause the only entity I have on that moment is the CompanyCar... and I can't use a FK (with FamilyCar PK) in this entity for each type of CompanyCar.

I really think this case is a 'is a' relationship. In the example with cars maybe dont get clear enough, so let me show the entity's real names.

There is a Supertype entity called PaymentAttempt with these fields: attemptId orderId ... ...

And a type of PaymentAttempt called PaymentAttemptDebit with these fields: attemptId bank account ... ...

And in the Code I receive the PaymentAttempt and want to specialize it to a PaymentAttemptDebit.

public void StartPaymentWorkflow(PaymentAttemptEntity paymentAttempt)
{
PaymentAttemptDebit paymentAttemptDebit = new PaymentAttemptDebitEntity(paymentAttempt.attemptId);
...
}
Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 25-Jan-2006 07:25:08   

But using a standard relationship I still need to map the fields manually.

What do you mean by that?

Please check the following thread for casting to sub-type: http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=5053

uranows
User
Posts: 6
Joined: 20-Jan-2006
# Posted on: 26-Jan-2006 17:48:48   

Cause If I use standard relationship the basic fields will need to be in the actual sub-type entity too.

Resuming what I want to do, is create the parent entity without specify what sub-type it is... cause the sub-type will be informed and filled later.

In code it is something like:

void FinalStepOfPreviousWorkflow(OrderEntity order)
{
   PaymentAttemptEntity paymentAttempt = new PaymentAttemptEntity();
   paymentAttempt.OrderId = order.OrderId;
   paymentAttempt.StartDate = DateTime.Now;
   ...
   ...
   paymentAttempt.Save();

   IAgents iAgents = AgentsFactory.Construct(order.PaymentAgent.AssemblyName, order.PaymentAgent.TypeName);
   iAgents.StartAgent(paymentAttempt);
}

void StartAgent(PaymentAttemptEntity paymentAttempt)
{
   //Here is the problem, cause if I fetch it, will fill the PaymentAttemptEntity
   //base fields normally into PaymentAttemptDebitEntity.

   PaymentAttemptDebitEntity debit = new PaymentAttemptDebitEntity(paymentAttempt.PaymentAttemptId);
   debit.Bank = XXX;
   debit.Account = YYY;

   //And when I Save it, will throw an exception informing that can't insert a
   //duplicated key (PaymentAttemptId) on PaymentAttempt table
   debit.Save();
}

LLBLGen permits that I add a Super-type Entity without specifying the Sub-type. And also permits I add a Sub-type Entity, but it will automatically create the data into Super-type Entity. Right? What I want is assuming that a Super-type is created, specify a Sub-type Entity to it, and be able to Save specific properties (sub-type properties) without it automatically create a new Super-type Entity for it.

Is that possible?

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 27-Jan-2006 06:41:39   

I was suggesting a 1:1 relation as such

void StartAgent(int paymentAttemptID)
{
PaymentAttemptDebitEntity debit = new PaymentAttemptDebitEntity();
debit.Bank = XXX;
debit.Account = YYY;
debit.PaymentAttemptId = paymentAttemptID;
debit.Save();
}