EF 4.1 and code first: still not ready…

After hearing lots of good things about EF 4.1 and its new code first approach, I’ve decided to take a look to see if it’s as good as they say. I must admit: the latest version has lots of good things, but it still is far far away from my favorite ORM (which, btw, is NHibernate). To test the code first approach, I’ve tried to build a simple model which reproduces most of the features I tend to use in day-to-day database persistence operations. This isn’t a real case example, but it’s close enough for seeing if it does what I want:

public class Address:ValueObject {
    private Address() {
        Street = Municipality = "";
    }
    public Address( string rua, string localidade ) {
        Street = rua;
        Municipality = localidade;
    }

    public String Street { get; private set; }
    public String Municipality { get; private set; }
}

public enum EntityKind {
    Individual,
    Coletiva
}
    public enum ContactKind {
    Phone,
    Email
}

public class Contact:ValueObject {
    public String Valor { get; private set; }
    public ContactKind ContactKind { get; private set; }

    public Contact( string valor, ContactKind contactKind ) {
        Valor = valor;
        ContactKind = contactKind;
    }

    private Contact() {
        Valor = "";
        ContactKind = ContactKind.Phone;
    }
}
public abstract class Entity:EntityWithAction {
    public String Name { get; set; }
    public Address Address { get; set; }
    public DomainAction Action { get; set; }
    public abstract EntityKind EntityKind { get; }

    private IList<Contact> _contacts = new List<Contact>();
    public IEnumerable<Contact> Contactos {
        get{ return new ReadOnlyCollection<Contact>( _contacts );}
        set { _contacts = new List<Contact>(value); }
    }
    public void AddContact(Contact contact) {
        _contacts.Add( contact );
    }
    public void RemoveContact(Contact contact) {
        _contacts.Remove( contact );
    }
}

public class Individual:Entity {
    public override EntityKind EntityKind {
        get { return EntityKind.Individual; }
    }
}
public class Company:Entity {
    public override EntityKind EntityKind {
        get { return EntityKind.Coletiva; }
    }
}

So, what do we have here:

  • we’ve got inheritance: just for the kicks, I want to have two different kinds of entity and they should be saved in the same table.
  • we’ve got components (I believe they’re called complex types in EF). Notice that Address is a component and Entity has a collection of components (Contacts).
  • I don’t want to allow direct access to  thecontact collection to anyone consuming my domain. All additions and removals should go through the Add/Remove methods.
  • I want to preserve my domain object’s behavior. I’ve got entities (ex.: Individual) and value objects (ex.: Address) with quite distinct behaviors. Notice also those ValueObject and EntityWithAction base classes… They’re inspired in the fantastic S#arch classes (whose use I recommend) and solve several interesting problems (like equality and hash computation) for entities and value objects.

After a morning trying to make my mappings work, I’ve simply quit. Here are some things which really bother me:

  • EF doesn’t seem to support collection of components. With NH, I can simply say that updating an entity should always delete and insert its contacts on a related table. Is this doable in EF? Because this kind of behavior shouldn’t require any back pointer in my Contact object…
  • EF requires the use of ICollection interface for associated entities. This isn’t really compatible with a real domain model where I do need to control what is done over an instance of an object.
  • There still isn’t enum support.
  • The fluent API for registering isn’t really that fluent. Worst: it has overloads of methods which return different types (yes, the CLR does support those overloads, but the C# will only allow it for different parameter lists). This leads to frustration really quickly. For instance, I’ve spent several minutes trying to define the discriminator column only to find out that the Require overloads return different results…which don’t “flow”…really…
  • I really didn’t get far enough to see if I could define the mapping at the field level, but I’m assuming that isn’t possible.

Probably these problems can be easily solved…probably not. I don’t know because I just gave up! Why did I gave up? Well, simply because there’s NHibernate which can do all this for me in a rather quick way, without any pain, and with very little changes in my domain model. And that’s why I’ll keep using NH for my domain and I’ll probably resort to EF for the reporting side of my apps…I’m sorry, but I think that EF is still nor ready for real domain models…

Advertisements

~ by Luis Abreu on May 12, 2011.

2 Responses to “EF 4.1 and code first: still not ready…”

  1. Olá Luis tudo bem?
    Parabéns pelo artigo, finalmente vejo algo assim, quando forçamos o EF ele não responde de uma boa forma. Já tive vários problemas com versões anteriores do EF, confesso que ainda não testei a 4.1, mas pelo que vi nos seus testes ainda falta muito para chegar perto de outros ORM´s.

    Novamente parabéns pelo artigo.

    • Bem, nao esta mau…mas para uso em modelos OO reais, esta ainda um pouco distante do que preciso…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: