Adapter and lazy-fetches

Posts   
 
    
sgay
User
Posts: 53
Joined: 23-Nov-2006
# Posted on: 01-Jun-2007 09:49:12   

Say I have the following structure: EntityA -> EntityB (1:n)

Say I fetch an EntityA:

EntityA a = new EntityA();
a.Id = 3;
adapter.FetchEntity(a);

And later on fetch related EntityBs:

EntityCollection<EntityB> bs = new EntityCollection<EntityB>(new EntityBFactory());
adapter.FetchEntityCollection(bs, a.GetRelationInfoEntityBs, ...);

Now, I'd like

  • bs[i].EntityA to be equal to (same object) a
  • only one roundtrip to the database, i.e. do not fetch EntityA again With the FetchEntityCollection above I assume that bs[i].EntityA will be null (no prefetch).

What would I need to do to achieve what I want?

  • Same query + prefetch path? But wouldn't that cause a second roundtrip to the database?
  • Create a context and add a and bs to it before fetching the collection?
  • ?
Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 01-Jun-2007 09:54:17   

Please try the following:

EntityA a = new EntityA();
a.Id = 3;
adapter.FetchEntity(a); 

// And later on fetch related EntityBs:

adapter.FetchEntityCollection(a.bs, a.GetRelationInfoEntityBs, ...); 
sgay
User
Posts: 53
Joined: 23-Nov-2006
# Posted on: 01-Jun-2007 11:08:23   

Walaa wrote:

Please try the following:

EntityA a = new EntityA();
a.Id = 3;
adapter.FetchEntity(a); 

// And later on fetch related EntityBs:

adapter.FetchEntityCollection(a.bs, a.GetRelationInfoEntityBs, ...); 

In the meantime, I have done some homework, and checked that:

  • A simple FetchEntityCollection(bs, ...) (i.e. on a new collection) does not load bs[i].EntityA.

  • Adding a prefetch path does load bs[i].EntityA but bs[i].EntityA != a, and it will use two queries.

  • Adding a context and no prefetch path does not load bs[i].EntityA.

  • Adding a context and a prefetch path does load bs[i].EntityA, and we have bs[i].EntityA == a, but it uses two queries (i.e. it tries to refresh a anyway).

What you propose does what I want. Many thanks!

I did not think about it because, in my mind, I was trying not to modify the EntityA, or planning for the case where a.bs would be hidden (i.e. the relation exists but EntityA does not expose it as a field).

Would there be a solution in that case?

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 01-Jun-2007 15:25:45   
  • A simple FetchEntityCollection(bs, ...) (i.e. on a new collection) does not load bs[i].EntityA.

  • Adding a prefetch path does load bs[i].EntityA but bs[i].EntityA != a, and it will use two queries.

  • Adding a context and no prefetch path does not load bs[i].EntityA.

  • Adding a context and a prefetch path does load bs[i].EntityA, and we have bs[i].EntityA == a, but it uses two queries (i.e. it tries to refresh a anyway).

Using a prefetchPath, will fetch entityA again. I thought you didn't want to do that.

the case where a.bs would be hidden (i.e. the relation exists but EntityA does not expose it as a field).

Would there be a solution in that case?

The following can do, and you won't need to fetch EntityA again.

EntityA a = new EntityA(3);
adapter.FetchEntity(a); 

//And later on fetch related EntityBs:

EntityCollection<EntityB> bs = new EntityCollection<EntityB>(new EntityBFactory());
adapter.FetchEntityCollection(bs, a.GetRelationInfoEntityBs, ...); 
foreach(EntityB b in bs)
{
    b.entityA = a;
}
sgay
User
Posts: 53
Joined: 23-Nov-2006
# Posted on: 01-Jun-2007 20:09:22   

Walaa wrote:

Using a prefetchPath, will fetch entityA again. I thought you didn't want to do that.

I didn't, which is why this option is listed as 'not applicable'.

The following can do, and you won't need to fetch EntityA again.

Errr.... sure. I had thought about that one simple_smile

Anyway, I know see clearly what I can and can not do.

Question considered answered. As usual, many thanks!