This is a migrated thread and some comments may be shown as answers.

SOA Application without using disconnected API

7 Answers 84 Views
Development (API, general questions)
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
gmendez
Top achievements
Rank 1
gmendez asked on 19 May 2010, 03:24 PM
Hello,

I'm developing a SOA Application, and some restrictions are imposed on it's design. The most important of them is that I'm not allowed to use the OpenAccess Disconnected API. I just can send plain DataContracts over the wire so automatic change traking is not available.

Another restriction is that every database access must be done through Stored Precedures.
I have managed to determine at the client side which objects within a collection where modified and send them to the service so the data can be updated in the database. The problem is that these objects are plain DataContracts so they are 'more than detached' from the scope :)

The only way I can figure out to update this data is to iterate through my DataContract objects collection and for each DataContract read the corresponding OpenAccess Object using a unique field (not the PK, I'm using Internal Key), updating my OpenAccess object and confirming the transaction. This means I must perform read and a write operation for each object.

However, since I'm accessing the database through stored procedures, OpenAccess defines an 'update' sp for each persistent object. May be I could call that sp directly passing the DataContract's data. The problem is that it requires the voa_version (by the way, it should be called 'toa_version' ;) ) and that information is not available at the datacontracts level.

I'm not sure if I will be allowed to include version info in my datacontracts. In case yes, is it possible to read that information so I can use it later?

Do you have any suggestion about this matter?

Thanks in advance, and best regards.

Gonzalo

7 Answers, 1 is accepted

Sort by
0
gmendez
Top achievements
Rank 1
answered on 19 May 2010, 06:49 PM
Hello again,

I've managed to get the version information for a persistent class like this:

 

 

IPersistentTypeDescriptor ptd = GetScope().PersistentMetaData.GetPersistentTypeDescriptor(o.GetType());

 

 

 

return Convert.ToInt16(ptd.PersistentVersion.GetValue(o));

 


As I told before, I must access the database using SPs. So OpenAccess generates SPs for inserting, deleting and updating objectes.

I reverse mapped a SP for updating objects and I got a static method that calls my SP. So far so good. The SP generated code is as follows:

USE

 

[WorkHoursService]

 

GO

/****** Object: StoredProcedure [dbo].[usr_update] Script Date: 05/19/2010 14:29:03 ******/

SET

 

ANSI_NULLS ON

 

GO

SET

 

QUOTED_IDENTIFIER ON

 

GO

ALTER

 

PROCEDURE [dbo].[usr_update] ( @usr_id INT, @default_role_id INT, @description VARCHAR(255) = NULL, @e_mail VARCHAR(255) = NULL, @is_active tinyint, @nme VARCHAR(255) = NULL, @passwd VARCHAR(255) = NULL, @user_id INT, @voa_version SMALLINT , @OLD_voa_version SMALLINT ) AS UPDATE [usr] SET [default_role_id] = @default_role_id , [description] = @description , [e_mail] = @e_mail , [is_active] = @is_active , [nme] = @nme , [passwd] = @passwd , [user_id] = @user_id , [voa_version] = @voa_version WHERE [usr_id] = @usr_id AND [voa_version] = @OLD_voa_version

 


In this situation, for me it's clear that I must pass the original version value for the OLD_voa_version argument. The question is: What value shoud I pass to the voa_version  argument?? For my first tests I'll pass the original version value in this case too, but I'm not sure this is the right approach. Any help will be very apraciated.

Best wishes,

Gonzalo
0
gmendez
Top achievements
Rank 1
answered on 19 May 2010, 07:05 PM
I have found this in the OpenAccess Help at Programming With OpenAccess > Metadata Extension Reference > db-optimistic-locking
This talks about the 'version' mechanism:

OpenAccess ORM uses this method by default for optimistic concurrency control. It uses a version column to detect concurrent updates. The version number is incremented on every update and the previous version number is included in the where clause. This is the fastest and safest optimistic concurrency control mode.

I guess this answers my question. This is the path I will follow even thought I won't be using the disconnected API. Just for a matter of consistency. If this is wrong, please tell me.


Best wishes,

Gonzalo


0
IT-Als
Top achievements
Rank 1
answered on 20 May 2010, 09:16 AM
Hi Gonzalo,

To me it looks like the perfect approach.

We have build a SOA application just like yours (SmartClient, WebClient, ServiceClient on the client tier and WCF services on the Application Server tier).
DataContracts flows between client and server (and includes both the id and version) of the entity the datacontract object represents (if it represents an entity)..
In each and every datacontract we have included an EditState (None, Dirty, New, Delete) which the client sets when it manipulates the entity retrieved from the server... (easily done if you databind the datacontract objects retrieved from the the server and the client - we use the property notify change event in our datacontracts).
When the datacontract objects (typically one would modify a graph of objects) are sent back the EditState is also returned... And the server inspects this EditState and decides what operation should be performed on the persistent model.

This approach might seems cumbersome, but it has proved to be very useful.

Regards

Henrik
0
gmendez
Top achievements
Rank 1
answered on 20 May 2010, 01:30 PM
Hello Henrik,

Thank you very much for your feedback.
Implementing INotifyPropertyChanged would be great and is something I've done before, as well as keeping track of the EditState. However my DataContracts are automatic generated by WSSF 2010 and unfortunately I must keep them as simple as possible, because obviously if I generate the code again from the WSSF 2010 model my DCs will be overriden. Besides, I'm not allowed to modify them anyway. Bad luck...  :(
I guess I'll have to give my web client more intelligence to call the right method of the service.
Thanks a lot.
Regards,

Gonzalo
0
gmendez
Top achievements
Rank 1
answered on 20 May 2010, 01:37 PM
I forgot, I'm not using concurrency control anymore, so I don't need to send the version inside the DCs because I don't have a version field  in my tables :)
0
IT-Als
Top achievements
Rank 1
answered on 20 May 2010, 01:43 PM
Hi Gonzalo,

OK, so you don't need the concurrency control.

We used a common base class which holds the logic to alter the EditState and all our DataContracts inherits from this common base class. I think there's an option to do so in the proxy generator (command-line although).

Just thought I wanted to share.

/Henrik
0
gmendez
Top achievements
Rank 1
answered on 20 May 2010, 03:39 PM
Hello Henrik

I used to be a software architect in my previous job so I had full power to make design desitions. I adapted the 3 layered architecture they had so the base class for business objects had a property called PersistenceState. It was of type enum and the possible values where:

  • New (When the object was just created)
  • Unchanged (When the object was even persisted into DB or read from DB without changes)
  • Modified (After reading the object from DB, if it had been changed)
  • Deleted (After deleting the object from DB. Object is not valid anymore).

The objects implement INotifyPropertyChanged. The setters update the persistence state from Unchanged to Modified so the objects automatically changes their state from the point of view of their clients.

These business objects were used by a Winforms application and also by a WCF application as Datacontracts, accessed by Silverlight (after reading the great articles by David Betz on the internet about this matter). This mechanism works great.

But now I'm using Web Services Software Factory 2010 and I'm new at this company. I'll have to gain their confidence before being allowed to introduce some of these ideas.

It was  a great pleasure to share thoughts with you. If you'd like to keep in touch I invite you to add me as a contact in linkedIn: http://uy.linkedin.com/in/gonzalomendezdiaz

Best Wishes,

Gonzalo

Tags
Development (API, general questions)
Asked by
gmendez
Top achievements
Rank 1
Answers by
gmendez
Top achievements
Rank 1
IT-Als
Top achievements
Rank 1
Share this question
or