views:

541

answers:

2

We have an ASP.Net MVC2 web site, and are utilizing EF4 for database access, etc. Being new to EF4, we have come across the EF4 POCO concept, however do not fully understand it.

In general, I've heard POCO defined as objects "not dependent on an external framework". In the case of EF4, I'm guessing this means that POCO would imply somehow creating lighter-weight entities? If this is the case, what EF4 plumbing does POCO not have, what are the pros/cons of this, what extra development work might one need with POCO. In summary, when is it good to use POCO in EF4?

+5  A: 

"POCO" is a vague term in the ORM space. People variously use it to mean:

  • "Pure" POCOs, which do no change tracking, lazy loading, have private properties, etc. They can be challenging to work with.
  • Psuedo-POCO proxies: The types with everything public virtual and which have different types at runtime.
  • Self-tracking entities. Not POCOs, but not EntityObject either.

I find the "not dependent on an external framework" definition to be somewhat self-serving. It's a way of ignoring the limitations of a framework. I.e., proxies are not real POCOs in my book, but they meet that definition.

What's wrong with EntityObject? Not a lot. It's fairly lightweight, and it's part of .NET. It's in the .NET 4 client profile, even. It doesn't even chain you to the EF. Although it would be sort of odd to use it as a "POCO type" with a different framework, it would work just fine. It's not in Silverlight, though, IIRC.

POCO entities are harder to work with, because you lose the stuff that EntityObject gives you for free. That's not a lot, but something to consider before chosing POCOs just because "they're cool," especially for those new to the EF.

One thing that a lot of people who get religious about POCOs tend to ignore: Mapping non-POCO types in no way limits you to exposing those non-POCO types externally. Your data services can project mapped non-POCO types onto unmapped POCO DTOs and you can choose to only expose those types, i.e.:

public IEnumerable<FooDto> IFooRepository.SelectAll()
{
    return from f in Context.Foos
           select new FooDto { Id = f.Id, Name = f.Name };
}

So mapping types and data service types can easily be different concerns, if you so choose.

When doe you absolutely need non-EntityObject types for mapping? Well, if you need self-tracking entities, then that's an open and shut case. If you must expose your mapped types to Silverlight, clearly then as well.

Beyond that it's less clear. If you're writing a data service for public consumption, then you should not make the DTOs be EntityObject subtypes, because that would stand in the way of plugging in a different framework later on. I would never make an immutable, public interface dependent on any one framework, even one included in .NET. On the other hand, as I said above, you can expose one type and map another; there's no requirement to expose mapped types, ever, and often very good reasons to not expose them (perhaps they contain non-public data).

Craig Stuntz
I'd like to add that I've been using POCO's now mainly just so I can add DataAnnotations to my properties, something that I don't think would be wise to do in the EF designer file as they could get nuked when updated. Although I probably should be using these on my View Models, it's just easier for most of my needs to add them right on the POCO's.
CannibalCorpse
@CannibalCorpse: EF classes are partial and there is no need to modify auto-generated code. There is no problem with using DataAnnotations with EF, you just have to use metadata classes.
LukLed
+3  A: 

I totally agree with Craig, POCO is something that harder to work with.

i will add more about the purpose of POCO, i hope you will understand when should use and when not to use it.

Model and Service is CORE

Model and Service is one of most important pieces of your application, it is a NO-NO-NO to change, you can't avoid to tightly couple model and service with any part of your application, thus small change of model require change of the whole application.

It is about flexibility

POCO is a matter of language-specific, not framework-specific. it is a simple class, that didn't has dependency with framework specific class, you can use POCO in all .net version including micro framework, and compact framework.

It is about Testing

POCO really easy to unit test because it doesn't have dependency with a non-unit-testing-friendly class.

It is about changes

Upgrade/Downgrade, make new client app in different environtment such as MONO? will be no problem, you can keep using your service and model, even for the most worst upgrade/down grade will only occur on View and Service Cotext Helper.

It is about natural

creating and working with POCO is easy and natural, you can write your business process clearly.

But remember POCO is not friendly with framework

I agree with Craig, POCO is TOO COOL, Too Cool to make friend with new people. look at WPF it is require a model that implement INotifyPropertyChanged, what you do to achieve that? you can make wrapper or you can make dynamic proxy of your model. but that require more advance technique and code to maintain.

ktutnik