views:

196

answers:

4

We have a WCF service that uses Entity Framework to query a SQL database. The WCF service is our data access layer. If any of our applications what to read/write data to and from the database, we call a method on the WCF service. The WCF service serializes the EntityObjects to the client apps.

In the client app (e.g. WPF app or ASP.NET app) we may update an entity property and call a WCF service, passing the entity as a parameter, to perform the database update. The entity that was updated may have hundreds of child entities related to it.

For example, a Customer entity will have a Projects property which is a list of Project entities. If our client app changes a simple scalar property on a Customer entity, like CustomerName, we need to save that change to the database by calling an update method on the WCF service. The issue is, we are passing the Customer entity to the service to be updated, but all the attached Projects are also being serialized and passed to the WCF service even though the WCF service update method is only concerned with changes to scalar properties on the Customer entity. Obviously, we are serializing and transferring much more data than is needed.

Has anyone had any experience with this issue? Somehow, I would like to only have the Customer entity serialized back to the WCF service, without doing a deep serialization of the entire object graph.

Thanks.

+1  A: 

I'm using hibernate (Java/grails) and trying to implement Hessian and am having the exact same problem - hessian seems to by trying to serialise the entire object graph but I only want one object. Did you come across a solution? The hessian documentation isn't exacty, err, overflowing with information or configuration options.

Fletch
No, I have not come across a solution yet.
ChrisNel52
+3  A: 

Either you limit what you want to transfer with DataAnnotations, or the better way would be, that you make a own Model on the data you want to transfer via wire. here, all intentions (mapping between database, mapping between service & client) have their own dedicated model.

the mapping between the 2 models can very easily be done with automapper.

cRichter
+1  A: 

You could use the maxItemsInObjectGraph property of the DataContractSerializer object to restrict the serialization. You can easily try it by using the configuration element in the behavior configuration. For instance

<behaviors>
<behavior name="CustomerUpdate">
<dataContractSerializer maxItemsInObjectGraph="1" />
</behavior>
</behaviors>

One other option I can think of is to create a DataContract Surrogate that removes the info you don't want serialized. To do so you should create a class that implements the IDataContractSurrogate and use the GetObjectToSerialize method to modify the Customer Entity to not include any of the related entities collections.

This approach really bothers me for a number of reasons

  • It requires a lot of effort, you may eventually build a behavior to simplify the reuse but that doesn't avoid the initial effort
  • I can't think of a generic way of handling this issue for all entities (unless you decide not to send all collection or enumerable properties)

So I would definitely try to use maxItemsInObjectGraph first

HTH

CriGoT
A: 

Well its not that easy to find solution to this problem... actually what you need is to track changes in your entities and mark them dirty respectively and then apply CURD/ operations to only those entities in object graph those have their dirty flag set.

Here is a similar discussion: http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/89b7087a-1b08-4fe0-9cc3-68986fe89a74

Regards.

Shoaib Shaikh