A few days ago I run into a very interesting issue with respect to the use of LINQ to SQL entities as service entities. To be more specific, I was working on a small proof-of-concept involving heavy use of LINQ to SQL. At some point, I had to exchange some of the data between two WCF services. Naturally, I thought on using the entities generated by the VS 2008 designer as service entities. That's the point where things started to become interesting. At first, I was happy to see that VS 2008 provides the SerializationMode property that indicates the need to decorate the generated classes with the DataContract / DataMember attributes. Basically, when you set SerializationMode to Unidirectional, the generated entities will be automatically decorated with the proper attributes enabling them to be used in WCF service exchanges. My happiness was rather short-lived when I realized there are things that you cannot influence. In my particular case, it was the inability to specify the namespace. But there are also other issues like required fields, ordering, and some more which prove to be difficult to address this way.
After analyzing the issue in more detail and discussing with some of my fellow RDs, I came to the conclusion that one cannot expect to use the generated LINQ to SQL entities in service exchanges directly. You will probably need to do some mapping in order to make things work. When it comes to mapping, you can approach the problem from two different angles.
First, you can create your own service entities plus some bits that transform your LINQ to SQL entities into your service entities. This helps you keep your service entities very clean and concise and also gives you the desired level of control. The downside of the approach is that you have to write several classes, thus adding some maintenance overhead.
The second approach (suggested to me by Clemens Vasters) does the mapping using the same class. Since LINQ to SQL is generating partial classes, it's quite easy to add something like this to the generated class:
[DataContract(Namespace = "http://mynamespace...")]
public partial class SomeClass
{
[DataMember(Name = "MyName")]
private string __Name
{
get
{
return Name;
}
set
{
Name = value;
}
...
}
}
This works because LINQ to SQL generates partial classed and because DataMember doesn't actually care about the visibility of the member it decorates. Consequently, you get the same level of control as in the first approach while retaining all your code in one single class. Obviously, the downside is that you get one class that is cluttered with a mix of LINQ to SQL and DataContract/DataMember stuff.
I really hope Microsoft is going to address this issue in the near future, but in the mean time we'll have to stick with one of the two solutions I mentioned.