Entity Framework 4.1: how to work with per call life time data context? - wcf

According to this post, I am using a data context per call, so in each method of my WCF service, I use a using block to create a new data context.
But I have some doubts in the form to work in this way.
For example, I use a method getAllCLients() from my repository to get all the clients of the data base, then the service send to the client that call the method a list with all the clients. Then the user modify the information of some of them, three for example. The modify client perhaps I can add to a list that have the modified clients.
When I want to update this three clients, I can call a method updateClients() which receive a list of modified clients. How I am use a new data context per each method, in updateCients() get a new dataContext, without entities, so I think that I have to follow this steps:
1.- create a new data context which has the clients that I want to update. SO I need to specified the conditions for that. This is an extra operation (I get the clients before with the getAllClients() method), so I need to get again the clients.
2.- go throw the clients collection of the DBSet (I use EF 4.1) and change the information. This makes me to go throw the list that I receive from the client application too. So I must to go throw two lists. This needs resources.
3.- save the changes. This is needed anyway, so it has no required more work.
There is any way to make the step 2 easily? exist some method in dataContext to pass the values from my modified client to the client in the data context? I use POCO entities, perhaps it exists an easy way to do that.
Other question is about concurrency. If I control the concurrency with pesimistic concurrency that allow EF (with a timestamp field for example), is it better to call the updateClient() one for each client or better to pass a list with all the clients? I mean that if I use a list as parameter, if there is a concurrency issue with one client,the second for example, the first client will be update correctly, but the second not and the third neither. How can I notify to the user that there is problems with some clients?
To resume, I would like to know the best way to make updates when I have a short life datacontext.
Thanks.
Daimroc.

The service is disconnected scenario so when your client passes backs modified records you just need to process them as modified. You don't need to load all records from database for that.
public void SaveClients(List<Client> modifiedClients)
{
using (var context = new Context())
{
modifiedClients.ForEach(c =>
{
context.Entry(c).State = EntityState.Modified;
});
context.SaveChanges();
}
}
If you are using per call service and every service operation needs context you can move your context instancing to service constructor because service instance will live only to server single service call = you don't need using for every call. If you do that don't forget to implement IDisposable on your service to dispose context.
Other question is about concurrency. If I control the concurrency with
pesimistic concurrency that allow EF (with a timestamp field for
example), is it better to call the updateClient() one for each client
or better to pass a list with all the clients?
EF doesn't support pesimistic concurrency out of the box. Using timestamp is optimistic concurrency because it allows others to use the record. Pesimistic concurrency is application logic where other client is not able to select locked record for update.
The concurrency is resolved per record but the problem in this case is transaction. Each call to SaveChanges results in transaction used to process all changes in the database. So if any of your modified records is not up to date you will get concurrency exception and whole transaction is rolled back = no record is updated.
You can still overcome the issue by passing list of modified records to the service (reducing roundtrips between client and service is a best practice) but you can process each record separately by calling SaveChanges for every single record. Anyway this should be very carefully considered because each call to SaveChanges is like separate unit of work - is it really what you want?
Btw. the best practice is to make your service statless. You should avoid maintaining data between service calls and this example really doesn't need it.

Related

Is it OK to flush the EntityManager from within a domain Service?

I have a domain service called OrderService, with a saveOrder() method:
class OrderService
{
// ...
public function saveOrder(Order $order)
{
$this->orderRepository->add($order);
// $this->entityManager->flush();
$this->notificationService->notifyOrderPlaced($order);
}
}
saveOrder() adds the order to the repository (which internally calls persist() on the EntityManager), then passes the Order to the NotificationService to send appropriate notifications (email, SMS).
The problem is, while NotificationService needs the order ID to include in the notifications, the Order has no ID yet as it's not been persisted to the DB (the ID is auto generated).
The obvious solution seems to pass the EntityManager as a dependency to the OrderService, and flush() right after the repository add() method, as in the example above. But I've always been reluctant to make the domain Services aware of the EntityManager, preferring to let them talk only to repositories, or other services.
What are the drawbacks, if any, of a domain Service having a dependency on the EntityManager?
Is there a better alternative?
Note: I'm using PHP and the Doctrine ORM, but I believe the same principles apply to Java & Hibernate as well.
You may want to consider one of these options (or both)
Make this service an Application layer service instead of a Domain service. It's perfectly OK to call your change tracker in an Application service since it is supposed to know about the application context and progress in the current use case. Typical application services will commit the business transaction/ask the change tracker to save changes when they're done, so why not call it to generate Id's as well ?
If you're concerned about the database being involved in the middle of a use case, maybe you can find an equivalent to NHibernate's Guid.Comb strategy to make your ORM generate an Id without issuing an INSERT to the database right away.
Use a Domain event. Upon creation, an Order could inform the world that it has been newed up. The notification service would handle the event and send appropriate notifications. You'll find an example of that here (it also includes an Application layer service to take care of the business transaction).

How can I get Entity Framework and WCF to work with transactions? Okay...what's the secret?

I've been trying several different ways in order to get a simple set of transactions to work for a simple WCF client/server situation. My WCF server has a class level declaration of the Entity Framework class for my database access and several methods to modify data and a method to SaveChanges. I'm using the Oracle Data Access (ODP.NET).
For instance I want to call a modification from the client and then a separate call to save the changes in the WCF service. It doesn't work. Basically, everything executes fine, but when the second call to save the changes is made, the WCF service no longer has the original context and therefore no changes are saved (and, consequently, the previous call that made the changes was automatically rolled back).
I'm utilizing Transaction scope around both operations in my client and executing Complete() after done. My WCF services have OperationContract's that use [TransactionFlow(TransactionFlowOption.Mandatory)] and those method implementations use [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]. Finally, my web config is configured with a wsHttpBinding that has the transactionFlow property set to True.
I'm having no luck. No matter what I try, when I try hitting the service for the follow-up save, the EF context is already renewed.
This has nothing to do with transaction. Transaction works on transactional resource but without calling SaveChanges in the first request there was no transactional resource active because EF context is not part of the transaction - the database is and the database is affected only when you call SaveChanges. To make this work you don't need distributed transactions. You need session-full service and store the EF context in the service instance. It a client uses the same client proxy instance to communicate with the service for all requests the communication will be handled by the same service instance = same EF context instance which will remember changes from previous calls.
IMHO this is very bad architecture. Simply don't use it. Expose specialized methods on WCF service which will do changes and save them. If you need to execute these methods in transaction with other transactional resources use the real distributed transaction.
this might be a reason. Since your are making an update in the different context. context doesn't know that the object is update to have say the context that the object is modified and then you call savechnages(). See if it helps

Validating a Self Tracking Entity (EF) through WCF

I'm having trouble defining what my OperationContract should be when adding / updating an entity. I want to send an entity (or list of entities) to the ObjectContext via the WCF Service (which will instantiate a Business Manager for me to do the actual validation).
If the entity passes all of the validation rules (which could very well require querying the database to determine pass/fail for more complex business rules), it'll be saved to the database, and I'll need to be able to pass back its ID (Identity Column primary key) and the value of the concurrency token (timestamp column), but if it fails, obviously we want to have a message or messages saying what was wrong. In the case of an update, all we would need would be the new value of a concurrency token, but again we'd want the validation message(s).
To make it trickier, an entity could have multiple child/grandchild entities as well. For instance, a Trip will have Stops, which could potentially have Orders.
I'm just wondering how people handle this in the real world. The simplest examples just show the WCF service's operations like:
[OperationContract]
bool AddEntity(Entity e);
[OperationContract]
bool UpdateEntity(Entity e);
Does anyone have any great ideas for handling this? I guess I'm really just looking for practical advice here.
Should we be trying to save a collection of objects in one service call?
Should we be conveying the validation messages through a fault contract?
Any advice/input would be helpful, thanks!
Should we be trying to save a
collection of objects in one service
call?
If you mean saving whole object graph in one call then the answer is definitely yes. If you mean saving multiple independent object graphs (collection) in one call then the answer is probably yes. It is good idea to reduce number of roundtrips between client and service to minimum but in the same time doing this can introduce complications. You must decide if the whole collection must be saved as atomic operation or if you are happy with saving only part of the collection and returning errors for the rest. This will influence the rest of your architecture.
Should we be conveying the validation
messages through a fault contract?
Yes but only if you will use save operation as atomic because fault contract is exception and exception should break your current operation and return only validation errors. It should be enough to have single fault contract which will transfer all validation errors. Don't fire the exception for each single validation error because it can make your application pretty annoying and useless.
If you want to save only part of the collection which passes validations and return errors for the rest you should not use fault contracts. Instead of fault contracts you should have some container data contract used for response which will carry both ids and timestamps for saved data and ids and errors for unsaved data.
One little note to STEs: Passing back just Ids and timestamps can be probably tricky. I'm not sure if you don't have to turn off tracking when you want to set them and after that turn the tracking on again.

Persisting multiple DTOs mapped to a single entity

I guess this has been asked before here , but I'm still confused about the correct approach to be taken.
I have a WPF client application which talks to a WCF service to retrieve data.
On the Service side , I have a large entity ( around 25 properties) and I have
three forms in my client app .
On each form, I need the facility to edit certain properties of my domain entity.
I do not want to return the large entity through the service as I need just 3-4 of its properties on each form.
Hence I have created three DTOs ( we are using AutoMapper) , one for each screen.
The service returns DTOs and this works very fine as far as the retrieval goes.
My question is how do I persist my DTOs.
We are using NHibernate in the service layer.
If I pass my partial DTOs to the service to persist , I would need to reload my large entity every time to perform the update.
Is this the only way to handle this scenario ?
What other options do I have if I need to display partial views of one single entity on the UI .. besides sending across the whole entity over the wire ..or creating three DTOs?
Thanks.
Using NHibernate in the service layer it is logical that you will need to either:
a) load the entity during an update operation at the service, modify the required properties and then commit your transaction, or
b) if you have the object already available at the service (but not associated with the NHibernate session) then you can modify the required properties, call session.Update(obj) to reassociate the object with the session and then commit your transaction.
We use the first approach regularly where we have hundreds of different entities in our model. We pass specialised command request objects from client to server and then our service layer is responsible for performing the work specified in the command requests.
Alternatively you could formulate a HQL query as outlined here. But this will quickly get pretty ugly and difficult to maintain.

WCF Data Services: Processing an object at save time

We are using a WCF Data Service to broker our data server side, and give third parties easy OData access to our data. The server side of things has been relatively easy. The client side, on the other hand, is giving us fits.
We are converting from regular Entity Framework to Data Services, and we've created an assembly which contains the generated client objects that talk to the data service (via a Service Reference). Those classes are partial, so we've added some logic and extended properties to them. This all works great.
The issue we are having is that we need to process our objects at save time, because they need to do some advanced serialization before they are sent over the wire. The DataServiceContext class contains two events: WritingEntity and ReadingEntity. The ReadingEntity event actually happens at the correct time for us (post object deserialization). The WritingEntity event happens at the WRONG time for us (post object serialization).
Is there any way to catch an object before it's written to the request, so that we can call a method on entity that is about to be written?
Obviously we could just loop through the Entities list, looking for any entity that is not in a state of Unchanged or Deleted, and call the appropriate method there...but this would require me to add special code every time I wanted to call SaveChanges on the context. This may be what we need to do, but it would be nice if there was a way to catch the entities before they are written to XML for sending to the service.
Currently there's no hook in the DataServiceContext to do what you want. The closest I can think of is the approach you suggested with walking all the entities and findings those which were modified. You could do this in your own SaveChanges-like method on the context class (which is also partial).