Inheritance - Polymorphic Fetch

Posts   
 
    
KastroNYC
User
Posts: 96
Joined: 23-Jan-2006
# Posted on: 26-Jul-2007 02:27:47   

I'm using adapter and i have the following hirearchy:

Provider - SuperType

ProviderMgmt - SubType ProviderIndy - SubType ProviderBrok - SubType

I want to do a polymorphic fetch of a single Provider Entity but i will not know before hand what type the Provider is?

Essentially I currently have the following code which is producing an error:


//id comes from querystring
ProviderEntity p = new ProviderEntity(id)

using (DataAccessAdapter da = new DataAccessAdapter())
{
      da.FetchEntity(p, null)
}

if(p.ProviderType == 1)
{
 //p must be a ProviderMgmt
 ProviderManagement pm = (ProviderManagement)p;  // throws error
}

Provider has a field which is used as a discriminator internally (I understand that LLBLGen does not use this discriminator when preforming polymorphic fetch) in another external app.

Why isn't this working?

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 26-Jul-2007 10:38:05   

ProviderManagement pm = (ProviderManagement)p; // throws error

That's by definition simple_smile You can't cast an instance of a superType(Generalized form) to an instance of a subType (Specialized form).

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39910
Joined: 17-Aug-2003
# Posted on: 26-Jul-2007 11:37:40   

What's the inheritance type? And more importantly: what's the error? Compile time? Runtime? If at runtime, what's the stacktrace?

Frans Bouma | Lead developer LLBLGen Pro
KastroNYC
User
Posts: 96
Joined: 23-Jan-2006
# Posted on: 27-Jul-2007 07:11:24   

I kept moving by using FetchCollection instead of FetchEntity and that seemed to provide the polymorphic fetch I was looking for. But it doesn't seem to be the best solution since i am sure before hand that I am only going to need one entity, i was hoping for a way to simply instantiate from the base class using the sytax


OrderEntity o = new OrderEntity(100);


Now if order 100 were a special subtype of order, lets say GoldMemberOrder I could simply do


if(o is GoldMemberOrder)
{
   GoldMemberOrder gmo = (GoldMemberOrder)o;
}

The above code scenario works fine as long as I use a FetchCollection so i'm going to stick with that unless someone can provide a better solution.

BTW, I did not keep track of the Error I was receiving but it basically said that Order was not of type GoldMemberOrder and could not be cast. I'll see if I can put it back into non-working order to get the actual message.

Thanks very much.

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 27-Jul-2007 09:35:53   

The above code scenario works fine as long as I use a FetchCollection so i'm going to stick with that unless someone can provide a better solution.

I don't know if it would be a better solution or not, but instead of casting to the subTypee, you can then fetch the subType from the database knowing its PK.

BTW, I did not keep track of the Error I was receiving but it basically said that Order was not of type GoldMemberOrder and could not be cast. I'll see if I can put it back into non-working order to get the actual message.

Most probably it was about that casting.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39910
Joined: 17-Aug-2003
# Posted on: 27-Jul-2007 10:44:52   

KastroNYC wrote:

I kept moving by using FetchCollection instead of FetchEntity and that seemed to provide the polymorphic fetch I was looking for. But it doesn't seem to be the best solution since i am sure before hand that I am only going to need one entity, i was hoping for a way to simply instantiate from the base class using the sytax


OrderEntity o = new OrderEntity(100);


Now if order 100 were a special subtype of order, lets say GoldMemberOrder I could simply do


if(o is GoldMemberOrder)
{
   GoldMemberOrder gmo = (GoldMemberOrder)o;
}

The above code scenario works fine as long as I use a FetchCollection so i'm going to stick with that unless someone can provide a better solution.

Erm, what you suggest can never work. OrderEntity o = new OrderEntity(100); // fetch o, no matter how if(o is GoldMemberOrderEntity) { // do things }

this code will ALWAYS skip the if statement, as o is already an instance of OrderEntity. So you already created an instance of a given type. That's not changeable into an instance of another type, it will after the instantiation always stay that type.

What you can also try is FetchNewEntity. So to fetch the order with id 100 in the right type, simply do: OrderEntity o = (OrderEntity)adapter.FetchNewEntity(new OrderEntityFactory(), new RelationPredicateBucket(OrderFields.OrderId == 100));

After THIS code, o can be a different type than OrderEntity, i.e. a subtype of OrderEntity or OrderEntity itself.

Frans Bouma | Lead developer LLBLGen Pro
KastroNYC
User
Posts: 96
Joined: 23-Jan-2006
# Posted on: 27-Jul-2007 18:33:54   

I don't know how I could have missed that method!?!? Thanks thats perfect.