5

I have some POCO objects that I'm using in an EF Code First context. So, when I fill them with data, I'm actually dealing with EF proxy objects rather than the POCOs themselves.

I have an ASP.NET MVC4 ApiController that returns my POCO objects, which I'll consume in my client application.

My "GET" method looks something like this:

    // GET api/Clients/5
    public Client GetClient(int id)
    {
        Client client = db.Clients.Find(id);
        if (client == null)
        {
            throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
        }

        return client;
    }

That doesn't actually work, because when the serializer tries to serialize the Client object, it's actually dealing with the EF proxy version, which causes it to hiccup. See Can an ApiController return an object with a collection of other objects?

So, I could turn off proxy generation by doing this to my DbContext:

    db.Configuration.ProxyCreationEnabled = false;

Which ensures that I'm dealing with the POCO rather than a proxy. But, now most of the members of my Client class are not populated, since it was the EF proxy that was lazy-loading those for me.

So what I really want is to use the EF proxy class to get the data, and then at the last minute return the original POCO from my method.

How can I do that without manually creating the whole object from scratch (including any nested objects) in code? Surely there must be an easy way - or at least a helper class of some kind?

Community
  • 1
  • 1
Gary McGill
  • 26,400
  • 25
  • 118
  • 202

2 Answers2

3

Your question involves how to design architecture for an application. Technically, there are more than more model in one application: Domain model, Data Transfer Object or View Model for different layers: Business logic layer, Distribution layer and Presentation layer.

Misuse of model in ASP.NET MVC, I see often to use Domain model (from EF) as view model because in some cases it is correct that domain model as view model is enough for your UI. But actually it's quite different, with complex UI, ex: grid, there might need more than one domain model to combine in one view model to provide data for your UI.

Similar with distribution layer, asp.net web api, consumers might need more than one domain model to do something. It is not usually 100% domain model as data transfer object.

So, for separation of concern, it would be suggested that you should create and separate DTO object with domain object (POCO object from EF), even it is mapped 1 : 1 in properties.

Example, if you have Customer domain model, you need to have CustomerDto.

You can map manually or use tool like AutoMapper, to map your domain model to DTO model.

With this way you also can avoid your problem stuff.

cuongle
  • 74,024
  • 28
  • 151
  • 206
  • 2
    +1 exposing DTOs to the remote client is the best way to go. It gives you full control over the data sent through the wire. – Wiktor Zychla Aug 01 '12 at 15:53
  • Thanks, I'll check out AutoMapper - it sounds like just the "helper class of some kind" that I was looking for. – Gary McGill Aug 01 '12 at 22:13
1

I known that you got the answer, but, may be you will want to take a look at this:

The POCO proxy type cannot be directly serialized or deserialized by the Windows Communication Foundation (WCF), because the DataContractSerializer serialization engine can only serialize and deserialize known types. The proxy type is not a known type. For more information, see the Serializing POCO Proxies section in the Working with POCO Entities topic. To serialize POCO proxies as POCO entities, use the ProxyDataContractResolver class to map proxy types to POCO types during serialization.

http://msdn.microsoft.com/en-us/library/vstudio/ee705457(v=vs.100).aspx

Alexis Pigeon
  • 7,423
  • 11
  • 39
  • 44
Vu Nguyen
  • 3,605
  • 3
  • 22
  • 34