Just a quick tip for those of you working with LINQ and WCF.
LINQ-to-SQL natively supports lazy loading as long as your entities are still managed by the DataContext. However, when you pass your entities across WCF your entities become detached from the DataContext so you can’t lazy load on the client side - which makes perfect sense.
The question is how do you then pass a LINQ entity and its child collections across WCF?
This is where the DataLoadOptions class comes in handy. This class allows you to specify exactly what child collections to load along with your entity.
Without this you would have to make two service calls - one to get the parent object and another to get the child collection.
Here’s how you use it:
Assume I want to get Customers and Orders from Northwind.
[OperationContract()] public IList<Customer> GetCustomers() { using (NorthwindDataContext db = new NorthwindDataContext(Settings.Default.ConnectionString)) { DataLoadOptions options = new DataLoadOptions(); options.LoadWith<Customer>(c => c.Orders); db.LoadOptions = options; return db.Customers.ToList(); } }
The DataLoadOptions class has a generic method called LoadWith<T>(Expression<Func<T,object>> expression). This method basically says, when you load the type T from the database also get the entities expressed by the lambda expression.
In the example above, we load Orders whenever we load Customer
Caveats
Because LINQ-to-SQL serialization is unidirectional, you cannot use the DataLoadOptions class to load a parent object. e.g. If I have an Order I can’t use the DataLoadOptions to load the Customer as well. This is done to prevent cyclic relationships.