|
I recently got to dig into LINQ to SQL for a little while. I'd been spending a lot of time with Astoria and LINQ to Entities, but as we know - Astoria and the Entity Framework don't currently work on VS 2008 Beta 2, so the only choice left when Astoria is missing is to write an .asmx service decorated with the [ScriptService] tag so that it exposes itself via raw XML (POX) instead of SOAP.
Everything in LINQ to SQL works splendidly - I defined my database, then I added a .dbml file to my project, dragged a couple tables onto the designer surface and built and I was ready to query - no worries. Then I tried to return an array of LINQ to SQL entities by calling .ToArray() on my results query. It would have worked fine, but there's a gotcha - if you happen to have a one-to-many relationship that, on the other side, is a one-to-one - you're going to run into a circular reference error and your results will fail to serialize into XML.
For instance, let's say you have a table called Products. Each product has a single Category (which is indicated by the CategoryID column). There's a right and proper foreign key relationship there, and assuming pluralization is working right - you're going to get a Product class with a Category property. This is fine. The Category class is where the problem occurs, because this class is, by default, going to come with a Products property that refers to all products in that category. While potentially handy, this is the source of the circular reference. To turn that property off, you just go into your data model designer and set "Child Property" on the Category table/class to "false". Now it will not generate a Products property and you can serialize the entire object graph without a problem.
If, at some point, you want to serialize all products that belong to a given category, you can just run a LINQ query against the products table and filter on Category.CategoryName or CategoryID - the property for walking backwards up the tree is not necessary in this case and it makes serialization impossible.
So, hopefully this little tip saves someone a couple hours of headache!