EntityCollection not really suited for WebServices?

Posts   
 
    
dion avatar
dion
User
Posts: 11
Joined: 23-Apr-2004
# Posted on: 23-Apr-2004 00:55:13   

I've been testing with a WebService to return an EntityCollection. My sample-data has an EntityCollection of 21 items, each item containing 66 columns (ok, this is a lot).

When I do a WriteXml() on the EntityCollection, I get a string containing 1.1Mb of chars!!! I think that's just too much data for a WebService to return, if you want good performance.

So here are the solutions I've tried to output smaller data from my WebService:

  1. Instead of using xml string output (by WriteXml()), I've used a binary formatter. This reduces the string to 580Kb.
  2. Removed the relations from my database. Now my output string is only 136Kb
  3. Used a TypedView (including all columns): only 14Kb !!!

Lessons learned: * If you don't really need a collection of Entities (but just a simple read-only list), use the TypedList or TypedView * For WebServices, don't use the WriteXml(), but use a binary formatter (this will make the output of your WebService unreadable, but is much quiker!)

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 23-Apr-2004 09:09:35   

The XML is verbose, however required, as it contains all the information to re-create the objects completely with all the state they contained. Webservices are problematic, because they always require the use of XmlSerializer. This class can't handle interface typed members and cyclic references. All objects in a hierarchy contain cyclic references (Customer.Orders contains order objects which have order.Customer set to the Customer containing Orders)

A lot of data exported into Xml is also resulting in a big datablob. You also have to make sure you haven't fetched a collection inside an entity if you don't want that. For example, you have a collection of Customers, and for one action you need to set an order value, and you do this (selfservicing) myCustomers[index].Orders[index2].SomeProperty = value; , you fetch all the orders for that customer. These are then also exported in the XML later on.

I wonder why a typed view is so small compared to a typed list, as both will contain the same data if you store the same fields in the typed list.

Frans Bouma | Lead developer LLBLGen Pro
dion avatar
dion
User
Posts: 11
Joined: 23-Apr-2004
# Posted on: 24-Apr-2004 06:06:54   

In fact, I didn't use the XmlSerializer, but the BinarySerializer; and then encode it's data to base64 chars. I guess the BinarySerializer is doing a better job on Interfaces?

Here is a snippet from my code; and it works for me (while keeping the output small)

[WebMethod] public string GetEntityCollection() { EntityCollection entColl = new EntityCollection(); //filled entColl here

//now serialize to bytes BinaryFormatter formatter = new BinaryFormatter(); MemoryStream writeStream = new MemoryStream();

formatter.Serialize(writeStream, entColl );

//now convert bytes to base64 chars return System.Convert.ToBase64String(writeStream.ToArray()); }

B.t.w.: TypedList and TypedView just gave me the same output-size.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 24-Apr-2004 09:13:44   

AH ok, I misunderstood you, this indeed is an ok way to do it, however XmlSerializer is always used, it will now still process the string returned from the method. The interface to prevent this, IXmlSerializable is undocumented because XmlSerializer always thinks an implementor of the interface is a dataset disappointed

Frans Bouma | Lead developer LLBLGen Pro