IPoco?
You've probably noticed by now that a new CTP of the Entity Framework has been released. One of the new features is oddly named IPOCO. This is supposedly a step towards persistence ignorance for users of the framework. While people are already having a laugh, trying to come up with the best explanation for what the acronym means, I decided to dig in and find out what this is.
There is little to be found in the bits or the sample code that show how you would write an IPOCO, but I found some information at the MSDN forums.
"Starting in the next CTP you will have the option to use IPOCO where instead of using the generated code you could write your own classes and as long as they have an appropriate attribute indicating that a property is part of the entity, then the framework can persist that property whether or not it's public."
Daniel Simmons - The System.Data.Objects Dev Guy
"You can derive from EntityObject (called Entity in CTPs before June) and implement the property getters/setters yourself. Unless you need IPOCO and the flexibility, deriving from EntityObject provides some of the implementation you would manually have todo with IPOCO.
Brain Dawson - ADO.NET Program Manager
Judging from this and a bit of peeking around in the System.Data.Entity namespace an IPOCO is a class which implements the IEntity interface and has a truckload of Edm* attributes sprinkled around. I'm might be wrong about this but an IPOCO probably looks something like this:
[Serializable]
[EDMEnityType]
[EdmRelationshipRole("FK_Order_Customer", "Customer",
RelationshipMultiplicity.ZeroOrOne, typeof(Order))]
public class Customer : IEntityWithRelationships
{
private static IEntityChangeTracker changeTracker=
new ChangeTracker(typeof(Customer));
private EntityKey id;
public EntityKey Id
{
get
{
return id;
}
set
{
changeTracker.EntityMemberChanging("Id");
id=value;
changeTracler.EntityMemberChanged("Id");
}
}
[EdmScalarProperty(IsNullable=false)]
public string Name
{
get
{
return name;
}
set
{
changeTracker.EntityMemberChanging("Name");
name = value;
changeTracker.EntityMemberChanged("Name");
}
}
// Lots of similar properties...
}
As far as I can tell you have some choices when it comes to the IEntityChangeTracker, either you use one of the built-in change trackers that require a truckload of constructor arguments like entity sets, object state managers, metadata and what not - or you roll your own (as I've done in this imaginary example).
Again, I might my sample might not be quite right, but I reckon I'm not totally off the wall. As Daniel pointed out in his blog post on the release of the new CTP "this is the first step in that direction (My addition: ...towards POCO) and makes the key change to allow the creation of Entity classes that do not inherit from our base class". IMHO, the ADO.NET team have a long way to go before they achieve persistence ignorance. Implementing an interface is really not an advantage over a base class (unless you need explicit interfaces to avoid name clashes), since you'll have to write all the code yourself. Change tracking and other needed features of an ORM are quite hard to get right, so if I'm right about this, we just got more rope to hang ourselves by from the entity framework. True persistence ignorance cannot be achieved until mscorlib is the only dependency required for an entity.