Entity Framework ‘Code First’ Approach and Domain-Driven Design

By | April 28, 2012

With the Code First approach we can create clean entities without any EF specific code. After the first demo, I saw that you have to deal with the IDbSet interface, which is placed in the Entity Framework library.
When you place the entities in your business dll you have to reference the EF library. This is a bit ugly. After some testing I saw that the IDbSet interface implements the generic IQueryable interface.
So it’s possible to cast the IDbSet to a more common interface.
In this example you will see how to use EF Code First without referencing the EF lib in your business library.

EDIT 15.04.2013:
Based on the user feedback, I decided to extend the VS.NET solution. The first version was focusing on the BL and DAL. The new version contains a possible end-to-end solution. -> ASP.NET MVC – BL – DAL (Entity Framework). What’s new?:

  • Dependency Injection: The CompositionRoot project contains the type mapping definition and is responsible for the type resolution.
  • The UI project references the CompositionRoot (for initializing at startup) and the Business (for accessing the business interfaces.)
  • And again: This blog post still focuses on the technical aspects of EF and persisting domain entities.

Here is a picture of my solution folder. The business dll references only the System lib. This project contains the core logic and the interfaces for the DAL.
The Domain folder contains the entities.

Solution Folder

Solution Folder


The context interface is clean. There are no EF specific types used:

public interface IContext
{
    IQueryable<Person> People { get; set; }
    IQueryable<Address> Addresses { get; set; }
    void Add<T>(T obj) where T : DomainObject;
    void Save();
}

And here are the entities:

public class DomainObject
{
    public Guid MyId { get; set; }
}

public class Person : DomainObject
{
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    public ICollection<Address> Addresses { get; set; }
}

public class Address : DomainObject
{
    public string Street { get; set; }
    public string City { get; set; }
    public int Zip { get; set; }
    public virtual Person Person { get; set; }
}

In the infrastructure library I created a context class which implements the IContext interface.

public class Context : DbContext, IContext
{
    public Context()
        : base("MyDb")
    { }

    public IDbSet<Person> PersonSet { get; set; }
    public IDbSet<Address> AddressSet { get; set; }

    public IQueryable<Person> People
    {
        get { return this.PersonSet; }
        set { this.PersonSet = (IDbSet<Person>)value; }
    }

    public IQueryable<Address> Addresses
    {
        get { return this.AddressSet; }
        set { this.AddressSet = (IDbSet<Address>)value; }
    }

    public IQueryable<TEntity> GetSet<TEntity>() where TEntity : class
    {
        return this.Set<TEntity>();
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Person>()
            .HasKey(x => x.MyId)
            .Property(x => x.MyId)
            .HasColumnName("Id");

        modelBuilder.Entity<Address>().HasKey(x => x.MyId);
            
        base.OnModelCreating(modelBuilder);
    }

    public void Add<T>(T obj) where T : DomainObject
    {
        this.Set<T>().Add(obj);
    }

    public void Save()
    {
        base.SaveChanges();
    }
}

The both public properties PersonSet and AddressSet are used by the EF. But for development, only the properties “People” and “Addresses” are important.
My Entities do not have any entity framework specific Data Annotations like [Key], [ForeignKey] etc.
This definition is made in the OnModelCreating method.
This is it!

Here is the source code.