views:

186

answers:

2

Hi,

I am trying to decide on an ORM tool for my project, and I am thinking about EF4.

What are the major (if any) annoyances/limitations with this product? Also, does it support caching?

Thanks

+1  A: 

This is a good place to start. Granted he's one of the main contributors of NHibernate so that particular post may seem a little bit biased, but there are some good links and arguments in the comments.

And looks like someone asked a very similar question on SO a few months back.

R0MANARMY
+1  A: 

The inability to use private backing fields for lazy loading collections. For example take this class:

public class Account
{    
  private IList<Customer> _customers = new List<Customer>();

  public IEnumerable<Customer> Customers
  {
    get { return _customers ; }
  }    

  public void AddCustomer(Customer customer)
  {

    //Perform some biz rules
    _customers.Add(customer)
  }
}

Access to the customers collection is restricted by using an IEnumerable collection and having a AddCustomer / RemoveCustomer methods on the class. Typically you want to do some business checking before adding or removing a new customer.

The current version of EF requires lazy loading collection types to be ICollection (or any type that implements ICollection). So the above class now would look like:

public class Account
    {    
      private IList<Customer> _customers = new List<Customer>();

      public virtual ICollection<Customer> Customers
      {
        get { return _customers ; }
      }    

      public void AddCustomer(Customer customer)
      {    
        //Perform some biz rules
        _customers.Add(customer)
      }
    }

Using a public ICollection Customers completely destroys good OO design principals as consumers could directly access by calling the Add Operation on ICollection.

Account acc = new Account();
acc.Customers.Add(new Customer()); //Bad code

The original intention of the domain class was to use the public add method:

Account acc = new Account();
acc.AddCustomer(new Customer());

NHibernate can handle this scenario through configuration. I would very much like to see this scenario supported in the EF.


Note however there is a workaround for the this limitation by declaring the the backing field as protected and map it through configuration:

public class Account
{    
  protected virtual ICollection<Customer> _customers = new Collection<Customer>();

  public IEnumerable<Customer> Customers
  {
    get { return _customers ; }
  }    

  public void AddCustomer(Customer customer)
  {

    //Perform some biz rules
    _customers.Add(customer)
  }
}

But this won't work if your application has a layered architecture (i.e your domain model is separated from EF configuration classes) because protected types are not accessible to external classes.

In order for this to work requires the EF classes to be in the same assembly as your domain models!

Lazing loading collections require a public or protected type that implements ICollection.