views:

2772

answers:

6

0 vote down star 1

I want to be able to share my datacontracts (classes generated in the linq to entities designer are decorated with the [DataContract] attribute.

I'm trying to use the architecture as detailed here: http://www.netfxharmonics.com/2008/11/Understanding-WCF-Services-in-Silverlight-2 and trying to reference my interfaces in my silverlight project using the 'Add as link' method as detailed here: http://www.netfxharmonics.com/2008/12/Reusing-NET-Assemblies-in-Silverlight

The problem I'm having is referencing my service interface in my silverlight project.

My solution has the following projects:

ORM - contains a Linq to Entities edmx model (namespace: company.client.Service) - the classes in this are decorated with DataContract attribute etc.

ServiceInterface - contains the interfaces (namespace company.client.Service) and a reference to the ORM for the classes (Customer etc) being returned

Service - contains the implementation of the service interfaces (namespace company.client.Service) and references ServiceInterface and the ORM for the classes.

ServiceHost - contains just .svc files as recommended in http://www.netfxharmonics.com/2008/11/Understanding-WCF-Services-in-Silverlight-2

WebSLHost - the host for the silverlight app

Gui - the silverlight GUI.

I want all the of the projects to be standard .net assemblies except for the silverlight gui of course.

When I try to add a link to my service interface files (as shown in http://www.netfxharmonics.com/2008/12/Reusing-NET-Assemblies-in-Silverlight) it give a compile error stating that it can't find the ORM and can't identify my entity types.

I want to be able to share the datacontract generated by the linq to entities generator with my service and the silverlight client, so if anyone has any ideas I'd appreciate them.

+4  A: 

What you are trying will only work with "full" .NET to "full" .NET (or at least, matched); and even then, it breaks the rules of SOA...

The whole idea of a data-contract is that you share the shape of the data, but not the implementation. This means that it doesn't matter that Silverlight doesn't know about EDMX, or some of the more unusual flavors of DataContract attributes (like callbacks) - the data is still intact.

By consuming the mex-generated version of the classes, you will still have the same essential data behaviour - that is the intended use-case of WCF with Silverlight. So just use a service reference. Alternatively, you'll need to have a DTO class that sits between the EDMX and WCF; as long as the DTO only uses WCF attributes (but no EDMX) you should be OK, but obviously this has a huge maintenance cost. I personally doubt that it is worth it in most simple scenarios.

Marc Gravell
OK, so if I'm using Linq to Entities in the background and the classes are decorated with [DataContract] and [DataMember] (for WCF serialization), is there no way to be able to reference these in my silverlight client? I thought if my service could return these types I'd be able to reference in SL?
Ciaran
The data-contract bits are fine; the problem is the EF base-class, that simply doesn't exist in Silverlight. You need either vanilla raw data-contracts, or mex-generated contracts.
Marc Gravell
+1  A: 

I still think your best bet is to NOT try to pass your linq-to-entities classes from your WCF component to your client. Instead, create simple DataContract classes that just hold the data (properties only). Fill that up on the WCF side, send it across and then in your client use the data to reconstitute a proper object you can use with linq.

Make sense?

Terry Donaghe
Ciaran
I have no problem passing around datasets, but I haven't tried what you're trying. If you figure it out, please share it here! :)
Terry Donaghe
+1  A: 

Unfortunately, LINQ to Entities classes expose some implementation features in their data contracts. They really would have done better to not make the classes be data contracts at all.

As has been said, simply create your own data contract (DTO) classes that match the shape of the data to be returned. Return individual instances of those classes, or List of them.

I recommend against using DataSet, DataTable or anything else platform-specific. The reason for this used to be that it did not interoperate with other platforms such as Java. However, I've seen situations where it doesn't interoperate properly within .NET - between different .NET versions, and I suspect between full .NET and Silverlight. Use a DTO, as above.

John Saunders
A: 

From what's been said here and from what I've read elsewhere it seems that EDM datacontracts just can't be shared with Silverlight in the manner I'd like.

However, it does look like it is possible to share linq to sql datacontracts with silverlight. Not exactly what I wanted but something I might consider. I'm just getting started with WCF and silverlight and haven't decided which is my best option as yet.

Ciaran
A: 

I'm trying to do the same thing and just posted on Silverlight.net forums.

If there isn't a way then what a terrible oversight by MS! Entities are the future, not many enhancements will be made to Linq to SQL in the future. Is it really that uncommon to want to use Silverlight + WCF + Entity Framework?? You're either stuck with separate entities in each service proxy namespace (this flat-out doesn't work in a real Silverlight application) or duplicating the schemas and translating between your customer schemas and the entity schemas, which takes away from the beauty and simplicity of Entity Framework.

Justin
A: 

I can see two possible solutions for this.

  1. Modify generated linq-to-entities classes by surrounding with preprocessor directives non-silverlight lines by

    if !SILVERLIGHT

    // Non silverlight code

    endif

  2. The other alternative is to convert your .NET assembly to Silverlight compatible one as described in this article: Converting .NET Assemblies to Silverlight Assemblies

Boris Modylevsky