Quantcast
Channel: entityframework Discussions Rss Feed
Viewing all articles
Browse latest Browse all 1793

New Post: Interface usage in DBContext

$
0
0
Hi Javed,

I have achieved this with EF 5.0. The solution is too complex to post. I can give a very high level description.

The base class for the repository looks like...
public class GenericRepository<TEntityInterface, TEntity> 
    where TDataInterface : TEntityInterface
    where TEntity : class, IBaseEntityInterface, new()
A subclass of this repository would look like...
public class EmployeeRepository<TEntity> : GenericRepository<IEmployeeEntity, TEntity>, IEmployeeRepository
where TEntity : class, IEmployeeEntity, new()
I use T4 templates to customize generation of entities to inherit entity interfaces, alternatively you could create partial classes for each EF entity to inherit interfaces. I've used code gen scripts to generate interfaces for the entities that correlate with the properties on the entities. All entities inherit IBaseEntityInterface.

At some point in your code (in my case using an INject injection framework), you marry the EF entity with the repository as so....
Bind<IEmployeeRepository>().To<EmployeeRepository<EmployeeEntity>();
Where EmployeeEntity is generated by the entity framework.

There is an issue with this approach, entity framework doesn't like LINQ joins between entity interfaces, doing so can result in an error, depending on how the query is structured.

You have to do the queries in the repository against TEntity. You can use navigation properties on entity interfaces (and on TEntity in the repository) to effectively do joins A-OK.

However sometimes you'll want to do joins without navigation properties, the work around is to expose methods on the repositories that return primitive IQueryable objects for use in other repositories e.g a query of IDs such as IQueryable<int> or codes IQueryable<string>, creating these within a repository for another repository to include them in a query.

I think on the whole, in a large code base, the benefits of using entity interfaces instead of directly referencing EF entity classes outweighs the problems you'll encounter using EF with entity interfaces. Apart from loose coupling, robustness to change etc, you can put a lot of code in the base repository and program against TEntity with the properties on your base entity interface.

e.g A method to get a collection of Entity interfaces matching a predicate with a number of properties pre-loaded
    public IList<TEntityInterface> Where(Expression<Func<TEntityInterface, bool>> predicate, params string[] includedProperties)
    {
        DbQuery<TEntity> query = Context.Set<TEntity>();

        foreach (string prop in includedProperties)
            query = query.Include(prop);

        return query.Where(predicate).ToList<TEntityInterface>();
    }
As far as I'm concerned referencing Entity Framework entities within your code is basically heavily coupling the code to the EDMX and hence to a specific database schema. If you have need to support multiple database schemas with the same code base, Entity Framework out of the box leaves you pretty high and dry.

Hopefully with future version of EF these issues will be resolved and we can all be good little programmers and use interfaces instead of EF classes without these sorts of tricks.

Viewing all articles
Browse latest Browse all 1793

Trending Articles