We've been developing a new app using the following stack:
SQL Server 2008 R2 -> Entity Framework 4.2 -> WCF Data Services -> WCF Data Services Client Library
This is all .NET 4.0
Now, the WCF Data Services Client Library is very convenient for small bits of data and simple schemas/object graphs, but it's a real dog for more complex models. In particular, we've found that the DataServiceContext.Links collection scales something like O(n^2): the more related objects you load in, and the more nested your graph, the slower it gets, till it takes longer to load data into the context than it does it read it off the wire.
For example, we have a collection w/ 2000 members, and each member has 4 navigation properties. Pulling the whole collection without expanding any navigation properties takes about 1 second. Expanding all 4 navigation properties takes 5 seconds. We've measured performance at various points in the stack, and the majority of the extra time is spent on the client, collating the data.
We've adopted various techniques to work around this for large data sets:
- Denormalization. This works well for those graphs that we always expand. Doesn't work so well if we want to defer loading of part of the graph.
- Loading related objects separately, and stitching them together outside the data context. This is just annoying, but it does overcome the context.Links problem.
- Using multiple data contexts to keep pressure on the Links collection to a minimum.
- Using MergeOption.NoTracking in connection w/ (1) & (2)
Does anyone know any other techniques? Is there a setting someplace that might be causing unnecessary overhead when loading related objects?
At times it seems like we are half-way to writing our own custom context, and I'd like a sanity check before it gets any more elaborate.
[Yes, I realize that WCF Data Services may be the wrong tool for the job. Alas, we are already down that road]