Search code examples
c#linqentity-frameworkdomain-driven-designobject-object-mapping

Is there a suggested pattern for using LINQ between the Model & DataAccess Layers in a DDD based Layered Architecture


I've been reading Tim McCarthy's awesome book on DDD in .NET. In his example application though, his underlying data access is using SqlCE and he's handcrafting the SQL inline.

I've been playing with some patterns for leveraging Entity Framework but I've gotten stuck on how exactly to map the IRepository linq queries to the underlying data access layer.

I have a concrete repository implementation called.

public EFCustomerRepository : IRepository<DomainEntities.Customer> 
{
    IEnumerable<DomainEntities.Customer> GetAll(
                     Expression<Func<DomainEntities.Customer, bool>> predicate)
    {
        //Code to access the EF Datacontext goes here...
    }
}

In my EF Model, I'm using POCO Entities but even so there's going to be no native mapping between my DomainEntity.Customer & my DataAccessLayer.Customer objects.

so I can't just pass Expression<Func<DomainEntities.Customer, bool>> predicate as the parameter for an EFContext.Customers.Where(...);

Is there an easy way to map an Expression<Func<T, bool>> predicate => Expression<Func<TOTHER, bool>> predicate

Or am I going about this all wrong ? Any suggestions / pointers appreciated.


Solution

  • From the code provided in your example I guess you are not using a generic repository pattern?

    I use EF CodeFirst (but it works for old EF to) with a generic repository pattern... http://average-uffe.blogspot.com/2011/03/repository-pattern-with-ef-code-first.html

    I do not have the Expression<Func<DomainEntities.Customer, bool>> in that post, but I always have a Find metod in the IRepository<T> interface.

    The interface:

    IEnumerable<T> Find(Expression<Func<T, bool>> expression, int maxHits = 100);
    

    And the implementation in the abstract baserepository:

    public virtual IEnumerable<T> Find(Expression<Func<T, bool>> expression, int maxHits = 100) {
        return this.DataContext.DbSet<T>().Where(expression).Take(maxHits);
    }
    

    And now you can call Find on any entity by a lambda expression...

    I can post a full example if you do not get it right, just say when.