Context, UnitOfWork2 and remoting

Posts   
 
    
mihies avatar
mihies
User
Posts: 800
Joined: 29-Jan-2006
# Posted on: 12-Jul-2006 13:42:14   

Here is my scenario. 1. client and server separated by internet 2. on client I am planning to use a Context on a form (simplified) where I'll put all of the partecipating entities. 3. upon save I'll create UnitOfWork2 and send it via remoting to server 4. Since I am using server populated field for concurrency I need to refresh entities that were saved

Questions: 3. Am I correct in saying that UoW2 is transferring only modified entities and not an entire graph 4. Is it possible to fetch back only updated entities when using UoW2 and then update the source context? Or do I have to do a manual refetch of all values?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 12-Jul-2006 17:01:31   

3: and the entities referenced by the changed entities. This is essential, as syncing info references these entities anyway. 4: You could try to fetch back the entities which are saved, though as remoting creates a copy, you should work towards: - start action -> load data -> modify data in screen/process -> collect data to send to service -> send data to service -> service persists data -> end action.

Frans Bouma | Lead developer LLBLGen Pro
mihies avatar
mihies
User
Posts: 800
Joined: 29-Jan-2006
# Posted on: 12-Jul-2006 22:09:30   
  1. So, hypothetically, if Order entity contains changes, UoW will fetch its Customer entity but not OrderDetails. Or will it include OrderDetails, too?
  2. Yes, Save and Close. But sometimes it is convenient to leave the form open for further changes (i.e one often saves sources in VS.NET (becuase it crashes here and there stuck_out_tongue_winking_eye ) and continue working without re-opening). Now, would this scenario work? a) send UoW over the wire b) save UoW with refetch c) loop through contained modified entities and extract Id, CuncurrencyField and store this pair + entity type. IOW save all EntityType,Id,ConcurrencyField triplet. d) Return all these triplets to client. e) update client entites (using entity type and id) with new concurrency values f) set client entities as !IsDiry and !IsNew

c) I think UoW exposes the modified entities, right? e) this should be straightforward using Context f) what would be the proper way?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 13-Jul-2006 11:29:18   

mihies wrote:

  1. So, hypothetically, if Order entity contains changes, UoW will fetch its Customer entity but not OrderDetails. Or will it include OrderDetails, too?

UoW won't fetch anything. You can specify if a SAVED entity is refetched. that's it. Fetching related data is not the purpose of a uow, as that would mean a lot of concerns were grouped into a single class, which isn't always a good idea

  1. Yes, Save and Close. But sometimes it is convenient to leave the form open for further changes (i.e one often saves sources in VS.NET (becuase it crashes here and there stuck_out_tongue_winking_eye ) and continue working without re-opening).

Then if you save, you've to refetch the data. Remoting isn't free nor transparent. It comes with a set of constraints, so you've to live with these. So if you send entities to the server, you've to be aware of the fact that the instances you have at the client are after that 'out-of-sync' and effectively have to be refreshed. best thing to do that is by re-starting the action, or better: design it in such a way that the action is restarted automatically.

Now, would this scenario work? a) send UoW over the wire b) save UoW with refetch

This is on the server, so unless you send the Uow back, you won't get the refetched data on the client!

c) loop through contained modified entities and extract Id, CuncurrencyField and store this pair + entity type. IOW save all EntityType,Id,ConcurrencyField triplet. d) Return all these triplets to client. e) update client entites (using entity type and id) with new concurrency values f) set client entities as !IsDiry and !IsNew

You can swap EntityFields2 objects between entities of the same type: myCustomer.Fields = myRefetchedCustomer.Fields; et viola, myCustomer has the same fields simple_smile . IsDirty is in that object. IsNew isn't.

c) I think UoW exposes the modified entities, right? e) this should be straightforward using Context f) what would be the proper way?

Context is an option. Though I still would opt for a simpler application design which streamlines this: if action is done, restart action, which automatically fetches the data for the action, which is up to date. Against popular FUD from some SOA fetisjists, SOA is something you have to design into your application: the communication between server and client isn't free nor transparent: it forces a given design upon you which affects the rest of the client application.

Frans Bouma | Lead developer LLBLGen Pro
mihies avatar
mihies
User
Posts: 800
Joined: 29-Jan-2006
# Posted on: 13-Jul-2006 11:39:36   

Hi Frans,

Yes, I understand what remoting means (out of sync, etc.)

You can swap EntityFields2 objects between entities of the same type: myCustomer.Fields = myRefetchedCustomer.Fields; et viola, myCustomer has the same fields . IsDirty is in that object. IsNew isn't.

Ok, good. How do I set IsNew not to be IsNew (like Commit does) and assign it a server generated ID?

Context is an option. Though I still would opt for a simpler application design which streamlines this: if action is done, restart action, which automatically fetches the data for the action, which is up to date. Against popular FUD from some SOA fetisjists, SOA is something you have to design into your application: the communication between server and client isn't free nor transparent: it forces a given design upon you which affects the rest of the client application.

Sure. I just want to minimize the bandwith.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 13-Jul-2006 12:26:01   

mihies wrote:

You can swap EntityFields2 objects between entities of the same type: myCustomer.Fields = myRefetchedCustomer.Fields; et viola, myCustomer has the same fields . IsDirty is in that object. IsNew isn't.

Ok, good. How do I set IsNew not to be IsNew (like Commit does) and assign it a server generated ID?

IsNew is a bool, you can just set it to false.

The PK field is in the Fields object, so you just swap it over and the PK is set. The EntityFields2 object can be seen as a DTO, which is its initial purpose internally simple_smile

Frans Bouma | Lead developer LLBLGen Pro
mdissel
User
Posts: 92
Joined: 16-Sep-2003
# Posted on: 13-Jul-2006 13:45:48   

Maybe it's an idea to create a sample for this scenario, many users will have this kind of architecture..

Thanks

Marco

Answer
User
Posts: 363
Joined: 28-Jun-2004
# Posted on: 13-Jul-2006 17:51:29   

Well, im sorta in the same boat. At first glance the UoW seems like a great fit, but i didnt end up using it, mainly becuase by passing a UoW your essentially bypassing your BLL as one could put any entity they want in there. IF your remoting your datalayer then its wonderful, and i considered doing this but decided against it as frans suggested somewhere that it would be too chatty.

What i do is create methods like this.

public VendorEntity SaveVendor(VendorEntity vendor, EntityCollection<VendorAddressEntity> vendorAddressesToDelete)

This allows me to perform the save for one screen in one go, so only 1 trip to the server, then after the BL does it stuff, it returns the modified Vendor (and all related entities) back to the client. I then basically clear out everything on the client and rebind using the new vendor entity that i recieved from the save (restarting the whole operation).