WCF DataServices & Mapped DTOs

I have a service with a domain model and I want to expose data to clients. The service has a typical architecture: a database, ORM (EF), a business layer with a domain model.

I want to use WCF DataServices to provide data to clients, but I cannot send data objects from the domain model to the client. I am going to use DTO to interact with clients, and I have a dto <=> data object mapping.

DataServices has a reflection provider, which in this case seems great (let’s consider a read-only script). But the reflection provider requires the IQueryable<dto> property, which must be set. And that is the problem. Therefore, I see the following ways to solve it:

  • Download all the domain objects, map all of them to dtos and return the result of dtos. A really bad approach if there are many domain objects.
  • Create the provider "linq2dto" and create dynamically the corresponding request "linq2EF", at the point of materialization of the request, get the data from db and perform the mapping. It sounds good, but as I see it, it is a difficult task.

So guys, I need some help. I do not want to write (and support!) The new linq provider. Maybe there is some kind of "common linq2anyware" implementation that I can use?

On the other hand, I really cannot provide data objects to the client and use the DataServices EF provider. Is there an easy way to implement such a mapping?

+4
source share
2 answers

Unfortunately, if you are really set to use DTO, you will need to do the work of translating the query tree to something that can use EF. This most likely puts you in the area of ​​custom providers, which is another problem you will have to deal with.

For a specific translation of the query tree, you can look at something like re-linq or IQ toolkit .

Can I talk briefly in the comments on the question of why do you need DTO? I think this question will be more useful to others if they can understand this detail.

+1
source

In short, write each DTO manually.

There may not be the answer you are looking for, but this is what I offer. If you cannot expose the actual type, write a light satellite type manually, for example

 class Foo { //large domain type FooDTO ToDTO() { return new FooDTO(...) } } class FooDTO { //lightweigh } 

I have not seen a single LINQ provider that can help you create a universal converter, but perhaps due to my limited experience. Another argument against using a generic converter is that domain types may require quite specific instructions on what to include in a lightweight object and what to exclude.

Alternatively, you can try to write a generic class that uses reflection to go through all the public properties and return you the serrialised object, but then you know the type of the object on the other end of the wire (if you cannot use your domain type) ?

+1
source

All Articles