Generically Implementing the Unit of Work & Repository Pattern with Entity Framework in MVC & Simplifying Entity Graphs

Update: 02/24/2014 – v3.2 released, improved API and reusable queries with the variation of the Query Object Pattern. Breaking change: Framework now ships returning all things TEntity or IEnumberable for compartmentalization, you will need to change the Repository.cs (see below, what methods signatures to change) if IQueryable is preferred over IEnumerable, IEnumerable is preferred as a best practice (http://genericunitofworkandrepositories.codeplex.com/documentation).

Update [01/06/2014] Quick start online video: http://blog.longle.net/2014/01/06/unit-of-work-unity-3-quick-start-video/

1-3-2014 5-43-38 PM

Update [11/18/2013]: Added mocked DbContext and DbSet and example Unit Tests using the mocks, download: https://genericunitofworkandrepositories.codeplex.com

This will be part two of a six part series of blog posts.

  1. Modern Web Application Layered High Level Architecture with SPA, MVC, Web API, EF, Kendo UI, OData
  2. Generically Implementing the Unit of Work & Repository Pattern with Entity Framework in MVC & Simplifying Entity Graphs
  3. MVC 4, Kendo UI, SPA with Layout, View, Router & MVVM
  4. MVC 4, Web API, OData, EF, Kendo UI, Grid, Datasource (CRUD) with MVVM
  5. MVC 4, Web API, OData, EF, Kendo UI, Binding a Form to Datasource (CRUD) with MVVM
  6. Upgrading to Async with Entity Framework, MVC, OData AsyncEntitySetController, Kendo UI, Glimpse & Generic Unit of Work Repository Framework v2.0

Update: 09/18/2013 – Sample application and source code has been uploaded to CodePlex: https://genericunitofworkandrepositories.codeplex.com, updated project to VS2013, Twitter Bootstrap, MVC 5, EF6, Kendo UI Bootstrap theme, project redeployed to Windows Azure Website.

Update: 07/30/2013 – To see this implementation with DI & IoC with EntLib Unity v3.0, see post: Bounded DbContext with Generic Unit of Work, Generic Repositories, Entity Framework 6 & EntLib Unity 3.0 in MVC 4.

Update: 06/21/2013 – Bug fix: Issue with deleting objects by Id in Repository.Delete(object Id). Updated blog post, and sample solution and added live demo link.

Live demo: http://longle.azurewebsites.net

First off let’s elegantly setup our solution, and prep it for real world development. We have our solution broken up into four different projects, now let’s talk about the “why?”.

5-8-2013 9-08-17 PM

Data Project (Data Access Layer)

This is where all of our ORM tooling related objects reside. In our case the EF (Entity Framework 6.0 Alpha 3) DataContext, Mappings, Migrations, etc. This give is nice separation, control and isolation of where any persistence related objects live. If ever, one day we need to change the tool of choice, or even upgrade, there’s only one layer or project to do this in, the Data project.

5-8-2013 10-08-26 PM

Entities Project (Domain Layer)
The Entities project is where all of our POCO (Plan Old C# Objects) objects will live. POCO’s should be very ignorant objects that pretty much have nothing in them but the structure of your data. With that being said, typically anything outside our Repository layer e.g. presentation layer (MVC), services layer (will cover in next post) should be completely ignorant to any persistence tool or technology e.g. NHibernate, eXpressPersistent, OpenAccess, EF (our case), etc.

5-8-2013 10-09-31 PM

Repository (Layer)
This is where our UoW (Unit of Work) pattern will be implemented as well as our Repository implementation. Our UoW implementation will handle most of our usual CRUD activities.

Two important objectives we will try to with our UoW pattern implementation are:

  1. Abstract away the ORM tool, in our case EF.
  2. Ensuring that all interactions with the database are happening under one DbContext instance per page request.

Obviously there are many other benefits, such giving us the ability to implement different variations of our UoW, potentially wire up to different types of repositories. For purposes of this article, we’ll stake focus on our two primary objectives, and I’ll cover the other benefits in later posts.

Web Project (Presentation Layer)
This is our presentation layer, for the purposes of the blog, we will use MVC (ASP.NET MVC 4). Again, this project should not have any dependent code on EF assembly, therefore that should not be any references to the EF assembly, it should only reference our Repository project for data access.

Refactoring the NorthwindContext for an Abstracted and Cleaner Implementation

Now that we’ve gone over the solution and it’s projects, let’s do a little bit of refactoring and cleaning up with our EF code.

Data.NorthwindDataContext.cs

Before:


    public class NorthwindContext : DbContext
    {
        static NorthwindContext()
        {
            Database.SetInitializer<NorthwindContext>(null);
        }

        public NorthwindContext()
            : base("Name=NorthwindContext")
        {
        }

        public DbSet Category Categories { get; set; }
        public DbSet CustomerDemographic CustomerDemographics { get; set; }
        public DbSet Customer Customers { get; set; }
        public DbSet Employee Employees { get; set; }
        public DbSet OrderDetail Order_Details { get; set; }
        public DbSet Order Orders { get; set; }
        public DbSet Product Products { get; set; }
        public DbSet Region Regions { get; set; }
        public DbSet Shipper Shippers { get; set; }
        public DbSet Supplier Suppliers { get; set; }
        public DbSet Territory Territories { get; set; }
        public DbSet Invoice Invoices { get; set; }


        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new CategoryMap());
            modelBuilder.Configurations.Add(new CustomerDemographicMap());
            modelBuilder.Configurations.Add(new CustomerMap());
            modelBuilder.Configurations.Add(new EmployeeMap());
            modelBuilder.Configurations.Add(new Order_DetailMap());
            modelBuilder.Configurations.Add(new OrderMap());
            modelBuilder.Configurations.Add(new ProductMap());
            modelBuilder.Configurations.Add(new RegionMap());
            modelBuilder.Configurations.Add(new ShipperMap());
            modelBuilder.Configurations.Add(new SupplierMap());
            modelBuilder.Configurations.Add(new TerritoryMap());
            modelBuilder.Configurations.Add(new InvoiceMap());
        }
    }

After:

     public class NorthwindContext : DbContext, IDbContext
    {
        static NorthwindContext()
        {
            Database.SetInitializer<NorthwindContext>(null);
        }

        public NorthwindContext()
            : base("Name=NorthwindContext")
        {
        }

        public new IDbSet<T> Set<T>() where T : class
        {
            return base.Set<T>();
        }

        public override int SaveChanges()
        {
            this.ApplyStateChanges();
            return base.SaveChanges();
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new CategoryMap());
            modelBuilder.Configurations.Add(new CustomerDemographicMap());
            modelBuilder.Configurations.Add(new CustomerMap());
            modelBuilder.Configurations.Add(new EmployeeMap());
            modelBuilder.Configurations.Add(new Order_DetailMap());
            modelBuilder.Configurations.Add(new OrderMap());
            modelBuilder.Configurations.Add(new ProductMap());
            modelBuilder.Configurations.Add(new RegionMap());
            modelBuilder.Configurations.Add(new ShipperMap());
            modelBuilder.Configurations.Add(new SupplierMap());
            modelBuilder.Configurations.Add(new TerritoryMap());
            modelBuilder.Configurations.Add(new InvoiceMap());
        }
    }

We can see that our DbContext is now much cleaner, and that it implements IDbContext. IDbContext will be the abstraction we will be working with when interacting with it’s concrete implementation, NorthwindContext.

Best Practice, Coding Against Abstractions or Interfaces

Abstractions serve as a nice flexibility point later, allowing us to implement different variations of the abstraction (interface). This will be very useful later when we implement DI (Dependency Injection and IoC (Inverse of Control) patterns. Coding to an abstraction will also help us easily create unit test, allowing us to inject faked or mocked instances as well. If your a bit unclear on how this helps set stage for DI, IoC and Unit Testing, no worries, I’ll cover these topics in the next post.

Data.IDbContext.cs


namespace Data
{
    public interface IDbContext
    {
        IDbSet<T> Set<T>() where T : class;
        int SaveChanges();
        DbEntityEntry Entry(object o);
        void Dispose();
    }
}

Now, let’s take take a look at what’s all in our Repository project, where our generic extensible repositories will reside.

5-10-2013 7-02-10 PM

IUnitOfWork This is simply the contract or abstraction that we will be working with, when interacting with it’s concrete implementation which will be UnitOfWork object.

Repository.IUnitOfwork.cs



namespace Repository
{
    public interface IUnitOfWork
    {
        void Dispose();
        void Save();
        void Dispose(bool disposing);
        IRepository<T> Repository<T>() where T : class;
    }
}

Concrete Implementation of IUnitOfWork.cs


namespace Repository
{
    public class UnitOfWork : IUnitOfWork
    {
        private readonly IDbContext _context;

        private bool _disposed;
        private Hashtable _repositories;

        public UnitOfWork(IDbContext context)
        {
            _context = context;
        }

        public UnitOfWork()
        {
            _context = new NorthwindContext();
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

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

        public virtual void Dispose(bool disposing)
        {
            if (!_disposed)
                if (disposing)
                    _context.Dispose();

            _disposed = true;
        }

        public IRepository<T> Repository<T>() where T : class
        {
            if (_repositories == null)
                _repositories = new Hashtable();

            var type = typeof (T).Name;

            if (!_repositories.ContainsKey(type))
            {
                var repositoryType = typeof (Repository<>);

                var repositoryInstance = 
                    Activator.CreateInstance(repositoryType
                            .MakeGenericType(typeof (T)), _context);
                
                _repositories.Add(type, repositoryInstance);
            }

            return (IRepository<T>) _repositories[type];
        }
    }
}

Let’s take a look at our IRepository Repository() method here in our UnitOfWork implementation. Here we are storing all the activated instances of repositories for each and every requests. One there is a request for a given repository we will first check to see if our Hashtable (container to hold all of our activated repository instances) has been created, if not, will go ahead and create our container. Next, we’ll scan our container to see if the requested repository instance has already been created, if it has, then will return it, if it hasn’t, we will activate the requested repository instance, store it in our container, and then return it. If it helps, you can think of this as lazy loading our repository instances, meaning we are only creating repository instances on demand, this allows us to only create the repository instances needed for a given web request. Last but not least, notice here how we are following best practices mentioned earlier, we are not return the concrete implementation for the Repository, but the abstraction, IRepository.

Repository.IRepository.cs


namespace Repository
{
    public interface IRepository<TEntity> where TEntity : class
    {
        TEntity FindById(object id);
        void InsertGraph(TEntity entity);
        void Update(TEntity entity);
        void Delete(object id);
        void Delete(TEntity entity);
        void Insert(TEntity entity);
        RepositoryQuery<TEntity> Query();
    }
}


Repository.Repository.cs


    public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
    {
        internal IDbContext Context;
        internal IDbSet<TEntity> DbSet;

        public Repository(IDbContext context)
        {
            Context = context;
            DbSet = context.Set<TEntity>();
        }

        public virtual TEntity FindById(object id)
        {
            return DbSet.Find(id);
        }

        public virtual void InsertGraph(TEntity entity)
        {
            DbSet.Add(entity);
        }

        public virtual void Update(TEntity entity)
        {
            DbSet.Attach(entity);
        }

        public virtual void Delete(object id)
        {
            var entity = DbSet.Find(id);
            var objectState = entity as IObjectState;
            if (objectState != null) 
                objectState.State = ObjectState.Deleted;
            Delete(entity);
        }

        public virtual void Delete(TEntity entity)
        {
            DbSet.Attach(entity);
            DbSet.Remove(entity);
        }

        public virtual void Insert(TEntity entity)
        {
            DbSet.Attach(entity);
        }

        public virtual RepositoryQuery<TEntity> Query()
        {
            var repositoryGetFluentHelper =
                new RepositoryQuery<TEntity>(this);

            return repositoryGetFluentHelper;
        }

        internal IQueryable<TEntity> Get(
            Expression<Func<TEntity, bool>> filter = null,
            Func<IQueryable<TEntity>,
                IOrderedQueryable<TEntity>> orderBy = null,
            List<Expression<Func<TEntity, object>>>
                includeProperties = null,
            int? page = null,
            int? pageSize = null)
        {
            IQueryable<TEntity> query = DbSet;
            
            if (includeProperties != null)
                includeProperties.ForEach(i => { query = query.Include(i); });

            if (filter != null)
                query = query.Where(filter);

            if (orderBy != null)
                query = orderBy(query);

            if (page != null && pageSize != null)
                query = query
                    .Skip((page.Value - 1)*pageSize.Value)
                    .Take(pageSize.Value);

            return query;
        }
    }

Our generic implementation for Repository allows us to have have all our basic heavy lifting of a Repository out of the box for any one of our Entities. All we have to do is request for the Repository of interest by passing in the Entity e.g.

UnitOfWork.Repository<Customer>

will give us the Customer Repository with all our out of the box plumbing available.

Let’s take a quick look at our Get method in the Repository implementation.


        internal IEnumerable<TEntity> Get(
            Expression<Func<TEntity, bool>> filter = null,
            Func<IQueryable<TEntity>,
                IOrderedQueryable<TEntity>> orderBy = null,
            List<Expression<Func<TEntity, object>>>
                includeProperties = null,
            int? page = null,
            int? pageSize = null)
        {
            IQueryable<TEntity> query = DbSet;
            
            if (includeProperties != null)
                includeProperties.ForEach(i => query.Include(i));

            if (filter != null)
                query = query.Where(filter);

            if (orderBy != null)
                query = orderBy(query);

            if (page != null && pageSize != null)
                query = query
                    .Skip((page.Value - 1)*pageSize.Value)
                    .Take(pageSize.Value);


            return query.ToList();
        }

The Get method here, handles fetching data. It handles querying the data supporting a filtering, ordering, paging, and eager loading of child types, so that we can make one round trip and eager load the entity graph.

We notice here that the method is marked “internal”, this is because we only want the Get method here to be accessible to objects with the same assembly, Repository.dll. We will expose the Get method via the Query method and return the RepositoryQuery object to provide a fluent “ish” api, so that’s its a bit more easy and intuitive for our developers when querying with our Repository layer. Note, only methods in our RepositoryQuery will actually invoke the internal Get method, again, which is why we went ahead and marked the Get method internal.

Repository.RepositoryQuery.cs (our fluent api helper class)


    public sealed class RepositoryQuery<TEntity> where TEntity : class
    {
        private readonly List<Expression<Func<TEntity, object>>> 
            _includeProperties;

        private readonly Repository<TEntity> _repository;
        private Expression<Func<TEntity, bool>> _filter;
        private Func<IQueryable<TEntity>, 
            IOrderedQueryable<TEntity>> _orderByQuerable;
        private int? _page;
        private int? _pageSize;

        public RepositoryQuery(Repository<TEntity> repository)
        {
            _repository = repository;
            _includeProperties = 
                new List<Expression<Func<TEntity, object>>>();
        }

        public RepositoryQuery<TEntity> Filter(
            Expression<Func<TEntity, bool>> filter)
        {
            _filter = filter;
            return this;
        }

        public RepositoryQuery<TEntity> OrderBy(
            Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy)
        {
            _orderByQuerable = orderBy;
            return this;
        }

        public RepositoryQuery<TEntity> Include(
            Expression<Func<TEntity, object>> expression)
        {
            _includeProperties.Add(expression);
            return this;
        }

        public IEnumerable<TEntity> GetPage(
            int page, int pageSize, out int totalCount)
        {
            _page = page;
            _pageSize = pageSize;
            totalCount = _repository.Get(_filter).Count();

            return _repository.Get(
                _filter, 
                _orderByQuerable, _includeProperties, _page, _pageSize);
        }

        public IEnumerable<TEntity> Get()
        {
            return _repository.Get(
                _filter, 
                _orderByQuerable, _includeProperties, _page, _pageSize);
        }
    }

Addressing IRepository<TEntity> Extensibility

Well, what happens if we need extra methods a specific Repository? Meaning, how do we address “extensiblility” in our Repository? No problem, we have a couple of options here, we can simply inherit a Repository and add your own methods to it, or what I prefer, create extension methods e.g. extending IRepository (with some pseudo code for validating an address with UPS).

Repository.CustomerRepository.cs

    /// <summary>
    /// Extending the IRepository<Customer>
    /// </summary>
    public static class CustomerRepository
    {
        public static decimal GetCustomerOrderTotalByYear(
            this IRepository<Customer> customerRepository, 
            int customerId, int year)
        {
            return customerRepository
                .FindById(customerId)
                .Orders.SelectMany(o => o.OrderDetails)
                .Select(o => o.Quantity*o.UnitPrice).Sum();
        }

    /// <summary>
    /// TODO:
    /// This should really live in the Services project (Business Layer), 
    /// however, we'll leave it here for now as an example, and migrate
    /// this in the next post.
    /// </summary>
        public static void AddCustomerWithAddressValidation(
            this IRepository<Customer> customerRepository, Customer customer)
        {
            USPSManager m = new USPSManager("YOUR_USER_ID", true);
            Address a = new Address();
            a.Address1 = customer.Address;
            a.City = customer.City;

            Address validatedAddress = m.ValidateAddress(a);

            if (validatedAddress != null)
            customerRepository.InsertGraph(customer);
        }
    }

Great, now that we have our project nicely structured with the our generic implementation of the Unit of Work and Repository Pattern, let’s see how we can leverage this by wiring up a simple controller to show a list of customers.

To help us with this go ahead and NuGet the PagedList for MVC so we easily create a view with a paged grid.

5-10-2013 6-22-37 PM

Let’s create a CustomerController Index Action load a paged list of customers to hydrate a grid.


    public class CustomerController : Controller
    {
        public ActionResult Index(int? page)
        {
            var pageNumber = page ?? 1;
            const int pageSize = 20;

            var unitOfWork = new UnitOfWork();

            int totalCustomerCount;

            var customers =
                unitOfWork.Repository<Customer>()
                    .Query()
                    .Include(i => i.CustomerDemographics)
                    .OrderBy(q => q
                        .OrderBy(c => c.ContactName)
                        .ThenBy(c => c.CompanyName))
                    .Filter(q => q.ContactName != null)
                    .GetPage(pageNumber, pageSize, out totalCustomerCount);

            ViewBag.Customers = new StaticPagedList<Customer>(
                customers, pageNumber, pageSize, totalCustomerCount);

            unitOfWork.Save();

            return View();
        }
    }

Next, let’s wire up the Index.cshtml view for our CustomerController Index Action.


@{
    ViewBag.Title = "Customers";
}

@using PagedList.Mvc;
@using PagedList;

<h2>Customers</h2>

<link href="/Content/PagedList.css" rel="stylesheet" type="text/css" />

<h2>List of Customers</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>
<table style="width: 100%; padding: 10px;">
    <tr style="background-color: lightgray; padding: 10px;">
        <th>#</th>
        <th>Company
        </th>
        <th>Name
        </th>
        <th>Title
        </th>
        <th>Order Date
        </th>
    </tr>

    @foreach (var item in ViewBag.Customers)
    {
        <tr>
            <td>
                @Html.ActionLink(
                    "Edit", "Edit", new { id = item.CustomerID }) |

                @Html.ActionLink(
                    "Details", "Details", new { id = item.CustomerID }) |

                @Html.ActionLink(
                    "Delete", "Delete", new { id = item.CustomerID })
            </td>
            <td>
                @item.CompanyName
            </td>
            <td>
                @item.ContactName
            </td>
            <td>
                @item.ContactTitle
            </td>
            <td>
                @if (item.Orders.Count > 1)
                {
                    @item.Orders[1].OrderDate.ToShortDateString()
                }
            </td>
        </tr>
    }


    <tr>
        <td colspan="9">
            @Html.PagedListPager(
                (IPagedList)ViewBag.Customers, page => 
                    Url.Action("Index", new { page }))
        </td>
    </tr>

</table>


Go ahead and run our project to see our paged customers grid.

5-10-2013 6-46-30 PM

Abstracting the Complexity when Dealing with Entity Graphs

Another item I wanted to go over was insert and updating graphs with our Repository pattern. There are four use cases for inserting graphs, they are as follows.

5-10-2013 7-34-28 PM

To abstract the complexity and EF experience required, and how the DbContext manages graphs e.g to know to set the root entity state and how it affects other entities in the graph (e.g. updating the root entity in the graph, and existing entities in the graph are to be updated or deleted) we added a interface IOjectState that all of our entities will implement.

Entities.IObjectState.cs


namespace Data
{
    public interface IObjectState
    {
        ObjectState State { get; set; }
    }
}

Entities.ObjectState.cs (enum)


namespace Data
{
    public enum ObjectState
    {
        Unchanged,
        Added,
        Modified,
        Deleted
    }
}

These two classes will allow our development team to explicitly set the state of each of the entities in the graph when inserting or updating a graph. To make use of the classes we’ll need to extend the DbContext with a few methods, we’ll do this by creating extension methods.

Data.DbContextExtension.cs


    public static class DbContextExtension
    {
        public static void ApplyStateChanges(this DbContext dbContext)
        {
            foreach (var dbEntityEntry in dbContext.ChangeTracker.Entries())
            {
                var entityState = dbEntityEntry.Entity as IObjectState;
                if (entityState == null)
                    throw new InvalidCastException(
                        "All entites must implement " +
                        "the IObjectState interface, this interface " +
                        "must be implemented so each entites state" +
                        "can explicitely determined when updating graphs.");

                dbEntityEntry.State = ConvertState(entityState.State);
            }
        }

        private static EntityState ConvertState(ObjectState state)
        {
            switch (state)
            {
                case ObjectState.Added:
                    return EntityState.Added;
                case ObjectState.Modified:
                    return EntityState.Modified;
                case ObjectState.Deleted:
                    return EntityState.Deleted;
                default:
                    return EntityState.Unchanged;
            }
        }
    }

Now we will override the SaveChanges in our NorthwindContext to invoke the ApplyStateChanges method to synchronize our ObjectSate with EF’s EntityState, so that the context will know how to deal with each and every entity when dealing with entity graphs.

Data.NorthwindContext.SaveChanges()


        public override int SaveChanges()
        {
            this.ApplyStateChanges();
            return base.SaveChanges();
        }


Now when inserting, updating you can explicitly set the entities state, especially useful when dealing with graphs. This abstracts the skill-set of a developer using our Repository of having to know the what, when and how to set the state of entities in the graph in order for the context to update the graph and persist the graph correctly. Let’s take a look at an example of updating an existing Order and adding an OrderDetail item with an entity graph. Both these actions, are will be executed on the same graph, however notice that the action is different for both of the entity’s, one is updating and the other is adding, however we will only be invoking one method (IRepository.Update(TEntity entity) from our IRepository in one transaction.

So we’ll demonstrate and prove out updating an entity graph with our UnitOfWork implementation in these steps.

Code Snippet from LinqPad, notice how we are explicitly setting each of the entities state in the entity graph.


var unitOfWork = new UnitOfWork(this);

var orderId = 10253;

unitOfWork
	.Repository<Order>()
	.Query()
	.Include(t => t.Customer)
	.Filter(t=> t.OrderID == orderId)
	.Get().Dump();

var order = unitOfWork
	.Repository<Order>()
	.FindById(orderId);

unitOfWork
	.Repository<OrderDetail>()
	.Query()
	.Filter(t => t.OrderID == orderId)
	.Get().Dump();

order.ShipName = "Long Le";
order.State = ObjectState.Modified;

order.OrderDetails.Add(
	new OrderDetail{
		ProductID = 2,
		UnitPrice = 10,
		Quantity = 2,
		Discount = 1,
		State = ObjectState.Added
	}
);


unitOfWork.Repository<Order>()
	.Update(order);

unitOfWork.Save();

new UnitOfWork(this)
	.Repository<Order>()
	.Query()
	.Include(t => t.Customer)
	.Filter(t => t.OrderID == orderId)
	.Get().Dump();
	
new UnitOfWork(this)
	.Repository<OrderDetail>()
	.Query()
	.Filter(t => t.OrderID == orderId)
	.Get().Dump();
		

Entity Graph Update Scenario

  1. Query the Order table, make note of the ShipName value.
  2. Query the OrderDetail table, make not there are only three (3) items, that belong to the same Order.
  3. Update the ShipName value in the Order.
  4. Add an OrderDetail to the Order.

5-11-2013 4-13-23 PM

(click image to enlarge)

Presto, we were able to successfully update an existing Order and add a new OrderDetail via an entity graph with one transaction using one method. Now, we can absolutely do this using EF out of the box, however, our goal here is was to abstract the complexity and skill set required from a developer in regards to EF specially how do deal with the DbContext in order to make this happen as well as obviously still support working with graphs through our IRepository implementation.

There you have it, and extensible genericized implementation of the UoW and Repository pattern with EF in MVC. In the next blog post, we’ll add DI & IoC to this solution and introduce the Services layer, this layer will house all of our business logic and rules. We will also implement the Services layer in a way, where we don’t violate our Unit of Work pattern, meaning all the work done in our Repository and Services are executed under one single instance the DbContext per page request.

Happy Coding..! :)

Download sample: https://genericunitofworkandrepositories.codeplex.com

About these ads

283 thoughts on “Generically Implementing the Unit of Work & Repository Pattern with Entity Framework in MVC & Simplifying Entity Graphs

  1. Hi Le,
    all my Entities inherit from : Entity.
    When i try to read Data from DB the exception is: {“Invalid column name ‘ObjectState’.”}
    EF 6.1.1 does query this column in my case. In Entity.cs the ObjectState Property is decorated with [NotMapped].
    Do you have any clue?

  2. In some cases it is necessary to see a change made directly in the database or by other program and is not reflected in the Repository queries. Apparently EF manages a cache when you make a query. How could we force EF to go again to the table and read the fresh data again?

    Thank you.

  3. Just desire to say your article is as surprising. The clarity in your post is just excellent and
    i could assume you’re an expert on this subject. Well with your permission allow me to grab your feed to keep up to date with forthcoming post.
    Thanks a million and please keep up the enjoyable work.

  4. This article is very helpful to me searching how to structure a real project. I read so many article so far but this one give me more explanation in why we have “it” in our code. I very enjoy this article. Thank you so much the author. I hope you will give more such helpful article day by day.

  5. Hello

    I have a problem and don’t know how to solve it.
    I used your idea of unit of work and generic repository building a WEB API on ASP.NET web api 2.0.

    My approach was building a “EF Designer from database”, so far I had to build web api using Stored procedures from the database, it worked, meaning that I could get data from the database and my application would not crash, and the first time I had to use a table from the database, my application would crash giving me the following error:

    {

    Resolution of the dependency failed, type = “Domain.WebAPI.Controllers.ProductController”, name = “(none)”.
    Exception occurred while: while resolving.
    Exception is: InvalidOperationException – The current type, Domain.Repository.Pattern.DataContext.IDataContextAsync, is an interface and cannot be constructed.
    Are you missing a type mapping?
    ———————————————–
    At the time of the exception, the container was:
    Resolving Domain.WebAPI.Controllers.ProductController,(none) Resolving parameter “productService” of constructor Domain.WebAPI.Controllers.ProductController(Domain.Service.Product.IProductService productService)

    Resolving Domain.Service.Product.ProductService,(none) (mapped from Domain.Service.Product.IProductService, (none)) 
    Resolving parameter "orderValuesRepository" of constructor      Domain.Service.Product.ProductService(Domain.Data.StoredProcedures.IDomainEntitiesStoredProcedures storedProcedures,   Domain.Repository.Pattern.Repositories.IRepository`1[[Domain.Data.OrderValues, Domain.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] orderValuesRepository, Domain.Repository.Pattern.Repositories.IRepository`1[[Domain.Data.OrderProviders, Domain.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] orderProvidersRepository) 
    
    Resolving Domain.Repository.Pattern.Ef6.Repository`1[Domain.Data.OrderValues],(none) (mapped from Domain.Repository.Pattern.Repositories.IRepository`1[Domain.Data.OrderValues], (none)) 
    Resolving parameter "context" of constructor Domain.Repository.Pattern.Ef6.Repository`1[[Domain.Data.OrderValues, Domain.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]](Domain.Repository.Pattern.DataContext.IDataContextAsync context, Domain.Repository.Pattern.UnitOfWork.IUnitOfWorkAsync unitOfWork) Resolving Domain.Repository.Pattern.DataContext.IDataContextAsync,(none)
    

    }

    from what I could see the unity dependency injection is the problem, meaning that for my stored procedures it worked and I had the following code:

    {

            container.RegisterType(new HierarchicalLifetimeManager())
                .RegisterType(new HierarchicalLifetimeManager())
                .RegisterType(new HierarchicalLifetimeManager())
                .RegisterType(new HierarchicalLifetimeManager())
    

    }

    in the ProductService class I had this:

    {

        private readonly IDomainEntitiesStoredProcedures _storedProcedures;
    
        public ProductService(IDomainEntitiesStoredProcedures storedProcedures)
        {
            _storedProcedures = storedProcedures;
        }
    

    }

    when I added the functionality for IRepository and IRepository
    the application crash, this is my implementation for ProductService:

    {

        private readonly IDomainEntitiesStoredProcedures _storedProcedures;
        private readonly IRepository _orderProvidersRepository;
        private readonly IRepository _orderValuesRepository;
    
        public ProductService(IDomainEntitiesStoredProcedures storedProcedures,
            IRepository orderValuesRepository,
            IRepository orderProvidersRepository)
        {
            _storedProcedures = storedProcedures;
            _orderValuesRepository= orderValuesRepository;
            _orderProvidersRepository= orderProvidersRepository;
        }
    

    }

    and for the UnitConfig file I just added the following lines:

    {

                container.RegisterType&lt;IRepository, Repository&gt;(new HierarchicalLifetimeManager())
                container.RegisterType&lt;IRepository, Repository&gt;(new HierarchicalLifetimeManager());
    

    }

    the controller file is the same for both:

    {

        private readonly IProductService _productService;
    
        public ProductController(IProductService productService)
        {
            _productService = productService;
        } 
    

    }

    I even try to eliminate the stored procedures and only have to work with a the table OrderValues to see if it is the problem and the same error was triggered.
    Can you point the obvious thing that I missed, sorry for the long comment, but I’m getting desperate.

    Thanks in advance.

  6. Why did you use reflection: Activator.CreateInstance to create repository. You could write:
    repositoryInstance = new Repository(context) ???

    • You can follow by simply entering your email in the follow box on the right, or following my on twitter: @LeLong37.

  7. Hi. I am currently exposing my repository through a service layer but I am having to do something like this;

    public interface ICustomerService : IService
    {
    }

    and inject this service into the class that has contains my business logic (I’m using Ninject).

    public class SomeCustomerClass : ISomeCustomerClass
    {
    [Inject]
    private readonly ICustomerService _customerService;

        public SomeCustomerClass (ICustomerService customerService)
        {
            if (customerService== null)
            {
                throw new ArgumentNullException("customerService is null");
            }
    
            _customerService = customerService;
    

    //etc etc…

    If I only need the generic get/insert/update etc (and I don’t need to extend these), how can I inject the generic service to SomeCustomerClass. It doesn’t seem like I should need to have an empty service class, just to expose the basic methods from the generic service class for the Customer

    I hope that makes sense. I’m still getting to grips with all of this…

    • Just inject IService, there is no need to create a class, if you absolutely don’t plan on adding anything custom to your Customer repository or if you don’t have any buisiness logic you’ll need to add to IService .

    • I’ve tried to just inject IService but it expects me to specify a type when I inject it. For example,

      public class SomeCustomerClass : ISomeCustomerClass
      {
      [Inject]
      private readonly IService _service;

          public SomeCustomerClass (IService service)
      

      {
      if (service== null)
      {
      throw new ArgumentNullException(“service is null”);
      }

              _service= service;
      

      etc etc

      What I want to do is inject it once generically, without specifying a type and use it throughout the class. I’ve tried but I haven’t been able to make that work.

      I will have business logic, but I only want to define a service class for a repository if I actually need to extend it. Right now I am defining a service class for each type and inheriting the generic service class, just to expose the basic insert/update etc for that particular repository (which means I am injecting about 8 different services into my class :-(). I’m pretty certain there is a gap in my understanding somewhere. I’m sure I shouldn’t need to do that. However, as I said I haven’t figured out to just inject the generic service into my class and I’m hoping you can point me in the right direction.

  8. I’m truly enjoying the design and layout of your
    website. It’s a very easy on the eyes which makes it much
    more enjoyable for me to come here and visit
    more often. Did you hire out a designer to create your theme?

    Superb work!

  9. I’m looking at this code sample that you have…

     public static IEnumerable GetCustomerOrder(
        this IRepository repository, 
        string country)
    {
        var customers = repository.GetRepository().Queryable();
        var orders = repository.GetRepository().Queryable();
    
        var query = from c in customers
            join o in orders on new {a = c.CustomerID, b = c.Country}
                equals new {a = o.CustomerID, b = country}
            select new CustomerOrder
            {
                CustomerId = c.CustomerID,
                ContactName = c.ContactName,
                OrderId = o.OrderID,
                OrderDate = o.OrderDate
            };
    
        return query.AsEnumerable();
    }
    

    How does this work?

    public static IEnumerable GetCustomerOrder(
        this IRepository repository, 
        string country)
    {
        var customers = repository.GetRepository().Queryable();
    

    I’m trying to write an extension method which relies on other repositories and I don’t understand how you can get call the order repository this way…. I’ve tried it and I get the error below which makes sense to me. The customer repository doesn’t know anything about order. How do I get this to work?

    Constructor on type ‘Repository.Repository`1[[Data.Order, Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]‘ not found.

    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: System.MissingMethodException: Constructor on type ‘Repository.Repository`1[[Data.Order, Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]‘ not found.

    Source Error:

    Line 60: var repositoryType = typeof(Repository);
    Line 61:
    Line 62: var repositoryInstance =
    Line 63: Activator.CreateInstance(repositoryType
    Line 64: .MakeGenericType(typeof(T)), _context);

  10. How to do you utilize “unit of work” and concurrency when you expose your extension method as demonstrated in this post (https://genericunitofworkandrepositories.codeplex.com/wikipage?title=Adding%20Custom%20Queries%20to%20Repository&referringTitle=Documentation). I would like to expose everything through a service layer.

    //exposing my extension method through my service layer in my class
    private readonly IMyService_myService;

    var resultsBySomeId = _myService.GetExtensionMethod(Id);
    return resultsBySomeId;

    //service
    public class MyService : Service, IMyService
    {
    private readonly IRepository _repository;

        public MyService (IRepository repository)
            : base(repository)
        {
            _repository = repository;
        }
    
        public IEnumerable GetExtensionMethod(int Id)
        {
            return _repository.GetExtensionMethod(Id);
        }
    
    }
    

    However, this doesn’t use unit of work…

    I can do it this way but then I am exposing the repository directly…

    var resultsBySomeId = unitOfWork.Repository().GetExtensionMethod(Id);
    return resultsBySomeId;

    Hopefully this makes sense and you can advise me.

    Thanks!

  11. How generic is this, really?

    Could I switch DB technologies (e.g. from SQL server to Oracle) or swap out EF for another ORM (e.g. NHibernate)?
    Could I move from EF+SQL Server to MongoDb+MongoDb C# driver?

    Have you tested your framework against any of those scenarios?

    I’d really like to see a proof of concept on how this framework can really support that.

    Kudos for the article.

  12. Hi Lee,
    I have been using your framework for my application. I am currently facing one major issue . When i include child type as it has parents key so it automatically include parents object which i dont want. Any idea how can i fix this.
    -Thanks

  13. Good afternoon Le,

    Quick question for you. How would you specify a controller that would need separate Data Contexts injected into it? For example, we have a Messages repo associated with Context A, and then a Logging repo associated with a completely different Context B. I am curious to see how you would break that down using Unity, specifically with injecting a single Unit of Work, and two IServices (MessagesService and LoggingService) that wrap your repositories.

    Thanks!

    • Not that it’s the same but I did something with StructureMap. I have a multi-tenant app with each tenant having a separate database. The DBName is stored in a central database against a user and resolved in the login page and assigned to a claim.

      public static IContainer Initialize()
      {
      ObjectFactory.Initialize(x =>
      {
      x.Scan(scan =>
      {
      scan.TheCallingAssembly();
      scan.WithDefaultConventions();
      });

                  x.For().Use().Named("MyUnitOfWork").Ctor("context").Is(ctx =&gt;
          {
                      return new MyContext(ClaimsPrincipal.Current.FindFirst("DBName"));
                  });
      
          });
          return ObjectFactory.Container;
      

      }

      MyContext is a partial class …

      public partial class MyContext
      {
      public MyContext(Claim dbClaim)
      : base(“Name=MyContext”)
      {
      if (dbClaim == null) return;
      var dbStringBuilder = new SqlConnectionStringBuilder(Database.Connection.ConnectionString)
      {
      InitialCatalog = dbClaim.Value
      };

              Database.Connection.ConnectionString = dbStringBuilder.ToString();
      }
      

      }

      Then in my controller I get the named unit of work loaded with the appropriate context for the user.

      public ClientController()
      {
      _unitOfWork = ObjectFactory.GetNamedInstance(“MyUnitOfWork”);
      }

      Kind of clunky but works fine for me.

    • I left out the real reason I went with named units of work …

      The Identity database also uses the same pattern …

      x.For().Use().Named(“MyIdentityUnitOfWork”).Ctor(“context”).Is();

      To get this in the controller you would use …

      _unitOfWork = ObjectFactory.GetNamedInstance(“MyIdentityUnitOfWork”);

  14. You actually make it seem so easy with your presentation but I find this topic to
    be actually something that I think I would never understand.
    It seems too complex and very broad for me. I’m looking forward for your next post, I
    will try to get the hang of it!

  15. Hi, i’ve implemented your Repo/UoW pattern. It has helped me immensely and I appreciate, but i have some obstacle, i have 2 layer: application service layer(this layer knows all logic of application, this calls the services, and controller the UoW), service layer(this is interacts with your code). Questions:

    1. I need to build options according to variable criteria. by example one search screen with options that not mandatory: i can search by each or merge depends of the user:
      1.1. by Name
      1.2 by Lastname
      1.3 by city
      1.4 by state

      the user can search only by name, or name and city, or name-lastname-city.

    2. I need to load entity depends of the options for example: in one load only need empresa-City, in other only doc and other all, depend of the user, how do i do to load by param with your Repository?

      public partial class Usuario
      {
      public int UsuarioID { get; set; }
      public string Name { get; set; }
      public string LastName { get; set; }
      public City City { get; set; }
      public Empresa Empresa{ get; set; }
      public virtual ICollection Sessions { get; set; }
      public virtual ICollection Docs { get; set; }

      }

      public class UsuarioService : eBusiness.Service.IUsuarioService
      {
      private readonly IRepository _usuarioRepository;

      public UsuarioService(IRepository usuarioRepository)
      {
          _usuarioRepository = usuarioRepository;
      }
      
      public Task&lt;IEnumerable&gt; GetAsync()
      {
          return _usuarioRepository.Query().GetAsync();
      }
      
      
      public Task&lt;IEnumerable&gt; GetAsyncWithParram(????????????????????????????)
      {
          return _usuarioRepository.Query(??????????????????????????).GetAsync();
      

      }

    public class UsuarioAppService
    {
    public async Task Searching(string name =null,string lastname =null,string city=null, bool active =null, bool varInclude=false)
    {
    UsuarioAppServiceModel mResult = new UsuarioAppServiceModel();
    if(name!=null)
    {
    query=????????;
    }

        if(lastname!=null)
        {
            query=????????;
        }
        if(active !=null)
        {
            query=????????;
        }
    
        if(varInclude)
            Include?????????=include(city, empresa)
    
            var musuario = await _usuarioService.GetAsyncWithParram(query??????????, Include?????????);
        else
                    var musuario = await _usuarioService.GetAsyncWithParram(query??????????);
            if (true)
            {
                mResult.Usuarioserviceresult = UsuarioAppServiceResult.Completado;
                mResult.UsuarioModels = musuario.ToList();
            }
            return mResult;
    
    
        }
    

    }

  16. I am not able to understand why you have added reference of repository project in Entities folder.
    This is creating unnecessary dependency of repository with entities project.
    Can’t we can create a separate project for Entity and objectstate and add reference to both repository and Entities project

    • Ajay, that is the route we took. We have a Common assembly that houses common Models and such, and reference it in both the Repo and Entity projects.

  17. This article is really awesome, but I have two questions:

    How to call stored procedure in extension method?
    How to join entity in DbSet which is not referenced by foreign key as navigation property in extension method?

    Thanks!

  18. Hi Le, I have few question:

    (1) I create function in Repository

    public virtual IEnumerable GetWithRawSql(string query, params object[] parameters)
    {
    return dbSet.SqlQuery(query, parameters).ToList();
    }

    But dbSet, doesn’t contain a definition ‘SqlQuery’. how to solve this?

    (2) I have code:

    unitOfWork.EmployeeRepository.dbSet.Where(e => e.PositionID == positionID).Select(
    c => new { EmpID = c.EmployeeID,
    FullName = (c.LastName + “, ” + c.FirstName + ” (” + c.Initial + “)”)
    }).OrderBy(o => o.FullName);

    have the same problem because IDbSet, is there other alternative with the code above if using Generic Repository?

    • You need to use IRepository.SelectQuery() method, which wrapps DbSet.SqlQuery, parameters shouldn’t be any different.

  19. Hi Le,

    When i try to update my transaction screen which actually gets value from various other tables, i get this error. need help?

    error:
    Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.

    • Here is my code:

      Controller:
      [HttpPost]
      public ActionResult Edit(mSubscription msubscription)
      {
      try
      {
      var subscriptionModel = new mSubscription()
      {
      SubscriptionId = msubscription.SubscriptionId,
      ApplicationId = msubscription.ApplicationId,
      SubscriptionTypeId = msubscription.SubscriptionTypeId,
      SubscriptionLevelTypeId = msubscription.SubscriptionLevelTypeId,
      DurationId = msubscription.DurationId,
      CurrencyId = msubscription.CurrencyId,
      Amount = msubscription.Amount,
      NoofAccounts = msubscription.NoofAccounts,
      Description = msubscription.Description,
      CreatedBy = msubscription.CreatedBy,
      CreatedOn = msubscription.CreatedOn,
      ModifiedBy = 1,
      ModifiedOn = DateTime.Now,
      Status = msubscription.Status
      };

      using (IDataContext context = new Server.Data.SubscriptionData.SubscriptionContext())
      using (IUnitOfWork _unitOfWork = new UnitOfWork(context))
      using (ISubscription subscriptionManager = new bizSubscription(_unitOfWork))
      {
      subscriptionManager.Update(Mapper.TranslateSubscriptionModelToSubscriptionDTO(subscriptionModel, new Subscription()));
      _unitOfWork.Save();
      }
      return RedirectToAction(“Index”);
      }
      catch
      {
      ViewBag.error = ScreenMessage.SubscriptionExists;
      return RedirectToAction(“Edit”, “Subscription”, new { id = msubscription.SubscriptionId, error = true });
      }
      return View();

      }

      Server code:
      public void Update(Subscription currentSubscription)
      {
      try
      {
      currentSubscription.ObjectState = ObjectState.Modified;
      _unitOfWork.Repository().Update(currentSubscription);
      }
      catch (Exception ex)
      {
      }
      }

    • Le,

      i found one more error while updating my transaction screen.

      error:
      An object with the same key already exists in the ObjectStateManager. The
      ObjectStateManager cannot track multiple objects with the same key.

      is there something wrong in my code?

  20. Do you have a spam problem on this site; I also am a blogger, and I was wanting to
    know your situation; we have developed some nice practices
    and we are looking to exchange strategies with others, please shoot me an e-mail if interested.

  21. Hi Le,

    I just DL your la release sources code form codeplex (v3.2)
    First very nice job ;)
    But 2 questions :

    Why there are some EF reference in repository ? I really think it must be out (form interfaces)
    Why there is difference between “source” and “sample” ? wich one is the last one or good one ?

    Thank

    • I am inclined to agree with @evil… To solve this problem, I extracted all I could into a Repository assembly, and then created a Repository.EntityFramework for the specific implementations… It has worked out much better for us, and several of the consuming projects / assemblies need a reference to the Repository assembly, but not full-blown Entity Framework.

      @Le, I would be happy to share our code in private if it is something you want to consider.

      Thanks!

    • Absolutely, could you please share this, let me know what works best, the CodePlex repo has been converted to Git so you can fork and add this into it and push back up, or just email me: LeLong37@gmail.com.

    • Yes, v3.2 was the first step in separating interfaces from concrete implementations so that we can prep for building nHibernate provider, obviously the abstraction isn’t completely done yet, hence the EF reference. The solution in sample “Northwind.sln” has the framework projects in it, the framework projects are physically located in source folder, in essence framework projects in Patterns.sln and Northwind.sln are the same projects.

    • I made the separation too, was easy.

      I started to create ASP.NET OWIN UserStore and RoleStore using the repository.
      I was thinking some method like GetOne and GetOneAsync can be cool. Or may be I miss something.
      May be I will put the code on my GitHub, if someone is interresting.

  22. I was wondering why the orderby is used like below:

    .OrderBy(q => q
    .OrderBy(c => c.ContactName)
    .ThenBy(c => c.CompanyName))

    Why are we not able to use it as below

    .OrderBy(q => q.LastName)
    .ThenBy(t => t.FirstName)
    .ThenByDescending(tb => tb.Address)

    I guess we could use it after .Get() but that would defeat the purpose correct?

  23. In your example you have this:

    var customers =
    unitOfWork.Repository()
    .Query()
    .Include(i => i.CustomerDemographics)
    .OrderBy(q => q
    .OrderBy(c => c.ContactName)
    .ThenBy(c => c.CompanyName))
    .Filter(q => q.ContactName != null)
    .GetPage(pageNumber, pageSize, out totalCustomerCount);

    Is there a way to select the columns you want returned instead of all of them? I need a .Select for the columns.

    var customers =
    unitOfWork.Repository()
    .Query()
    .Filter(q => q.ContactName != null)
    .Select(
    s =>
    new
    {
    s.CustomerID,
    s.FirstName + ” ” + s.LastName
    }
    )
    .Take(10)
    .ToArray();

    I am assuming the GetPage handles the .Take(10)?

    I need something like this because I am using an auto complete controller for jQuery auto complete and I only need to return the ID and the name concated together.

    • I believe I figured it out. I forgot to add .Get()

      var customers =
      unitOfWork.Repository()
      .Query()
      .Filter(q => q.ContactName != null)
      .Get()
      .Select(
      s =>
      new
      {
      s.CustomerID,
      s.FirstName + ” ” + s.LastName
      }
      );

  24. Hi Le,

    Thanks for posting this!

    From what I can see, you don’t utilize any of your Services from your Controllers. I’d like to know how to inject a service into a controller, and then call several of its’ methods under a single unit of work (as you don’t expose Save() to the Services).

    For example, how would I inject a CustomerService into a controller, and in a single request then add a few new customers using the service, then save this unit of work?

    Thanks, Mick

  25. Hi Le,

    is there any way to use multi-level includes in your implementation?

    Normally in Entity framework, you can do this:
    Something.Include(Function(x) x.Company).Include(“Company.Employe”)

    I can’t seem to find a way to do that with your repository.

    Thanks

  26. Hi Le,

    thanks for the article. can you answer few of these questions:

    1- can i use repository pattern with UOW without using asp.net mvc application.
    2- can i avoid using the below code. i mean i do not want my controller to know about the context and _unitOfWork.
    3- _unitOfWork.Save(); can i avoid calling this save() method explicitly.

    [HttpPost]
    public ActionResult Create(mSubscription subscription)
    {
    try
    {
    using (IDataContext context = new Server.Data.SubscriptionData.SubscriptionContext())
    using (IUnitOfWork _unitOfWork = new UnitOfWork(context))
    using (ISubscription subscriptionManager = new bizSubscription(_unitOfWork))
    {
    subscriptionManager.Add(Mapper.TranslateSubscriptionModelToSubscriptionDTO(subscription, new Subscription()));
    _unitOfWork.Save();
    }
    return RedirectToAction(“Index”);
    }
    catch
    {
    return View();
    }
    }

    4- i’m using db first approach in EF. and the context class extends the DbContext. But your article points at context class extending the DataContext class.

    To resolve this issue i added a partial class,
    public partial class SubscriptionContext : DataContext
    {
    public SubscriptionContext()
    : base(“name=SubscriptionContext”)
    {
    }

        public new IDbSet<T> Set<T>() where T : class
        {
            return base.Set<T>();
        }
    }
    

    db first approach:

    public partial class SubscriptionContext : DbContext
    {
    public SubscriptionContext()
    : base(“name=SubscriptionContext”)
    {
    }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            throw new UnintentionalCodeFirstException();
        }
    
        public virtual DbSet<Application> Applications { get; set; }
        public virtual DbSet<Currency> Currencies { get; set; }
        public virtual DbSet<Duration> Durations { get; set; }
        public virtual DbSet<Subscription> Subscriptions { get; set; }
        public virtual DbSet<SubscriptionLevelType> SubscriptionLevelTypes { get; set; }
        public virtual DbSet<SubscriptionTask> SubscriptionTasks { get; set; }
        public virtual DbSet<SubscriptionType> SubscriptionTypes { get; set; }
        public virtual DbSet<TaskManager> TaskManagers { get; set; }
        public virtual DbSet<TenantSubscription> TenantSubscriptions { get; set; }
    }
    
      1. Absolutely, one of the design principles was to be able to use it on other implementation types e.g. ASP.NET WebForms, WinForms, WPF, WCF, Windows Services, Command Consoles, etc.

      2. Yes, and it’s actually best practice so that your Controllers to not know about UnitOfwork, you need to wrap this into a Service, please watch this Video on a simple implementation of this.

      3. No, you need to call the Save explicitly, this is by design, because you want to have granual control of when and where to commit the unit of work, allowing you to be decisive, this allows you to build up the Unit Of Work and commit when you think makes the most sense e.g. Instead of calling the database 10 times, you can build up 10 steps and roll this into one Unit Of Work and make one call to the database (depends on your use case) / chucky vs. chatty, either way you need granular control of when and where to commit.

  27. I tried to follow this pattern but I find it hard to Unit Test because of extension methods. Is there any way to make Unit Testing easy?

  28. Hi, thanks for the framework.

    I am having trouble testing with the fake dbsets, especially with relations in objects.

    I tried one of the tests in your project and modified it so that we verify that the supplier of the product is also not null. (see code below)

    I can’t make that test pass.

    Am I doing something wrong? Or is there a problem with the fake dbsets?

    Thanks

    [TestMethod]
    public void DeepLoadProductWithSupplier()
    {
    using (IDbContext northwindFakeContext = new NorthwindFakeContext())
    using (IUnitOfWork unitOfWork = new UnitOfWork(northwindFakeContext))
    {
    unitOfWork.Repository().Insert(new Supplier { SupplierID = 1, CompanyName = “Nokia”, City = “Tampere”, Country = “Finland”, ContactName = “Stephen Elop”, ContactTitle = “CEO” });
    unitOfWork.Repository().Insert(new Product { ProductID = 2, Discontinued = true, ProductName = “Nokia Lumia 1520″, SupplierID = 1, ObjectState = ObjectState.Added });

                unitOfWork.Save();
    
                Product product  = unitOfWork.Repository<Product>().Query().Include(x => x.Supplier).Filter(t => t.ProductID == 2).Get().FirstOrDefault();
    
                Assert.IsNotNull(product);
                Assert.IsNotNull(product.Supplier);
            }
        }
    
    • The mocked DbSet doesn’t support relationships, it’s meant for quick, simple Unit Test, I would highly recommend you setup Integration Test for your use case. You would need to setup a Test database with seed data and destroy the test database when your test are complete since you are testing if things are persisted or not.

      
      #region
      
      using System.Data.SqlClient;
      using System.IO;
      using Microsoft.SqlServer.Management.Common;
      using Microsoft.SqlServer.Management.Smo;
      using Microsoft.VisualStudio.TestTools.UnitTesting;
      
      #endregion
      
      namespace Northwind.IntegrationTest
      {
          [TestClass]
          public class ProductTest
          {
              [TestInitialize]
              public void TestInitialize()
              {
                  const string connectionString = "Data Source=.;Initial Catalog=Northwind;Integrated Security=True";
                  var fileInfo = new FileInfo(@"C:\Scripts\instnwnd.sql");
                  var script = fileInfo.OpenText().ReadToEnd();
                  var sqlConnection = new SqlConnection(connectionString);
                  var server = new Server(new ServerConnection(sqlConnection));
                  server.ConnectionContext.ExecuteNonQuery(script);
              }
          }
      }
      
      
  29. Great post – can you suggest a way to use the pattern and also be able use a subquery? – analogous to below

    using (var db = new xxxEntities())
    {
        var orders1 =
        (from order in db.Orders
            where !db.Orders.Any(otherOrder =>
            otherOrder.RiskId == order.RiskId &&
            otherOrder.DateTimeOrdered < order.DateTimeOrdered &&
            otherOrder.DateTimeOrdered > EntityFunctions.AddDays(order.DateTimeOrdered, -30))
         select order
         ).ToList();
    }
    
    • Could you post the the attempted query using the Repository your having? It should look something like this:

      
      var orders =
      _unitOfWork.Repository<Order>
      	.Query()
      	.Filter(t => t.RiskId == order.RiskId &&
      		t.DateTimeOrdered < order.DateTimeOrdered &&
      		t.DateTimeOrdered > EntityFunctions.AddDays(orderr.DateTimeOrdered, -30))
      	.Get()
      	.ToList();
      
      
  30. Le, very informative post – thank you.

    I’ve been trying to use this pattern with a subquery and have been hacking away at it to make it work with no success. Could you perhaps explain a bit on how to get something akin to the below to work? The code below works when the var db is an out-of-the-box database-first generated context. However I’m getting various errors in converting that to a repository pattern; they all relate to the subquery: where !db.Orders.Any …

    using (var db = new xxxEntities())
    {
    var orders1 =
    (from order in db.Orders
    where !db.Orders.Any(otherOrder =>
    otherOrder.RiskId == order.RiskId &&
    otherOrder.DateTimeOrdered < order.DateTimeOrdered &&
    otherOrder.DateTimeOrdered > EntityFunctions.AddDays(order.DateTimeOrdered, -30))
    select order
    ).ToList();
    }

    • I got teh subquery to work by using CreateObjectSet – see below. What’s a good way to account for this in the Repository pattern?

      ObjectContext objectContext = ((IObjectContextAdapter) _context).ObjectContext;
              ObjectSet<Order> objectSet = objectContext.CreateObjectSet<Order>();
      
              var orders = from order in _context.Set<Order>()
                           where !objectSet.Any(
                                     otherOrder =>
                                     otherOrder.RiskId == order.RiskId &&
                                     otherOrder.DateTimeOrdered < order.DateTimeOrdered &&
                                     otherOrder.DateTimeOrdered > EntityFunctions.AddDays(order.DateTimeOrdered, -30))
                               select order;
              return orders.ToList();
      
  31. On my way to an AngularJS/jQuery/Bootstrap-Client being delivered from a minimalistic ASP.NET MVC site and consuming an ASP.NET web v2 service (all using OWIN/Kathana infrastructure with bearer auth module from MS) I found upida.net useful. Probably that eliminates some of the wireing logic in your UoW code?! Might be useful.

    • I’m looking at the same type of client and back end structure. Can you expand on how upida.net was useful to you? Also, how does anything you mentioned in your post relate to the wiring logic of the UoW?

  32. Very good article. How would I retrieve a newly inserted ID after executing “_context.SaveChanges()”?

    • ID’s are hydrated in the entity, e.g. if you pass in a new Customer to be inserted, check the Customer.CustomerID after IUnitOfWork.Save() is invoked.

  33. Is it possible to use the repository pattern somehow through a wcf Service? We need to have the database Access (dbcontext) on a seperate machine. Unfortunately I can’t find a working solution.

  34. Hi Lee, I have followed your tutorial and I am getting a ‘The entity type User is not part of the model for the current context.’ error. I’m new to Code First approach, previously used DBFirst but wanted to implement Repo Pattern and UoW.

    The Entity Framework power tools auto generated some extra DBSet properties on my auto generated DbContext derived class. Something I don’t see in your example? So far I’m pretty cluless. How would you go about inveestigating this error?

  35. Good evening all…

    We have been implementing the UoW pattern documented here with much success. Thanks again, Le!

    Recently though, we have run across something that I wanted the group’s opinion on… We currently have some stored procedures that return distinct lists of various fields from our DB, and these distinct list of values will then drive drop-down lists in the MVC GUI… The problem we have is that the returned data is basically just a list of strings (Ex. A List of Machine names from a web farm that would have written to the log DB; WEB1, WEB2, WEB3, etc.). These lists are not going to be maintained (we would never execute any CRUD operations against them), and they therefore do not derive from EntityBase. Due to them not deriving from EntityBase, we cannot ask the IUnitOfWork for the appropriate Repositoty().

    // No good, as the return from usp_Get_Distinct_Machine_List is a list of strings, and does not map to the Log TEntity
    var machineQuery = _unitOfWork.Repository().SqlQuery(@”usp_Get_Distinct_Machine_List”);

    Thoughts on the most appropriate way to access this data? Do we go directly to the IDBContext for this type of data (I don’t know why, but that feels ‘wrong’)?

    Thanks much!

    • hi mrbaseball2usa, quick question, although we are not executing any CRUD against these lists, what would be the negative side effects if we created a first class citizen entity (something simple that would suffice as a container for a list of strings) and have this class inherit EntityBase? Although these class(es) inherit EntityBase, we would not register this with the Context builder.

    • Hi Le,

      So we started down that route last evening before I had heard back from you (great minds think alike!).

      We created a DropDownListItem model that inherits from EntityBase:
      public class DropDownListItem : EntityBase
      {
      [Key]
      public string ItemText { get; set; }

      public override string ToString()
      {
      return ItemText;
      }
      }

      And mapped the object in the Context:
      protected override void OnModelCreating(DbModelBuilder modelBuilder)
      {
      base.OnModelCreating(modelBuilder);

      modelBuilder.Entity();
      }

      The two important elements are making the ItemText a key (EF complained that the DropDownListItem had no Primary Key otherwise), and registering the new entity in our Context class…

      Thanks much!

  36. Hi. Very useful information! Thanks a lot!

    I`ve found one problem using Migrations with Generic Repository.

    1)The Seed Method takes MyContext as a parameter.
    Then, inside of it we addOrUpdate some data to the context and then save the changes.

    protected override void Seed(MyContext context)
    {
    var users = new List
    {
    new User …..,
    new User
    };
    users.ForEach(usr => context.Set().AddOrUpdate(p => p.UserName, usr));
    context.SaveChanges();
    }

    2)Running Migrations: update-database causes such an error
    “AcceptChanges cannot continue because the object’s key values conflict with another object in the ObjectStateManager. Make sure that the key values are unique before calling AcceptChanges.”

    This error occurs in DataContext.Savechanges() method due to SyncObjectsStatePreCommit(); or
    SyncObjectsStatePostCommit(); methods because when I comment these two methods – Migrations work fine.
    public override int SaveChanges()
    {
    //SyncObjectsStatePreCommit();
    var changes = base.SaveChanges();
    //SyncObjectsStatePostCommit();
    return changes;
    }
    The way out is:
    1) I have to use in Seed(MyContext context) method MyContext as DbContext
    2) Mark Savechanges() in MyContext and DataContext classes as new, not override them
    Then everything works fine.
    Mayby you could suggest any better solution?
    Thanks.

    • Thanks for the positive feedback Alex, unfortunately I haven’t had the time to figure out an more elegant way to handle the Code-First approach, if you figure a better approach than what you have already so far, please let us know.

  37. Would like to see this pattern integrated with ASP.NET Identity membership.

    I haven’t been able to merge MyIdentityDbContext (derived from the AspNet* identity tables and inheriting from DbContextBase) with the ApplicationDbContext …

    public class ApplicationDbContext : IdentityDbContext

    MyIdentityDbContext overrides OnModelCreating to change the schema name from “dbo” to “myschema” but it is never called by the AccountController …

    public AccountController()
    : this(new UserManager(new UserStore(new ApplicationDbContext())))

    I would like the one Identity DbContext inheriting from both IdentityDbContext and DbContextBase

  38. Pingback: Unit of Work & Repository Framework with ASP.NET MVC 5, Entity Framework 6 & Unity 3 (Quick-Start Video) | Long Le's Blog

  39. Hi,
    I am joining with others that this is simply fantastic series of posts, kudos!
    I have one question regarding LINQ SelectMany extension method usability with UoW/Repository implementation that you’ve crafted.
    Given that I use Entity Framework as O/RM: how will EF behave (or is it supported by your implementation) if I construct a query that basically uses sub query (IQueryable) as selector argument for SelectMany? To be exact: this argument is not a collection on any DbContext known entity type.
    It works well with entities’ collection properties; and also it works directly on DbSet property and SelectMany selector LINQ expression also starts off from some DbContext’s DbSet property.
    I have UoW/Repository implementation that (currently) exposes IQueryable and I receive nice YSOD that states “LINQ to Entities does not recognize the method ‘System.Linq.IQueryable`1[MVC.Models.Domain.Core.Expense] Queryable(System.Linq.Expressions.Expression`1[System.Func`2[MVC.Models.Domain.Core.Expense,System.Object]][])’ method, and this method cannot be translated into a store expression.“

    Some code that is involved:
    These are lines that produce error:

    var qry = this.uow.Expenses.Queryable()
    .Where(e => e.Id == id)
    .SelectMany(e => this.uow.Expenses.Queryable()
    .Where(r => e.Related != null && r.Related == e.Related)
    .DefaultIfEmpty(e));
    var relatedModels = qry.ToList();

    Entity that is subject for this query (removed code that should not be relevant here):
    – Related property denotes some optional relation between Entities, although it is not defined in db or EF CF mapping level.

    public class Expense
    {
    public int Id {get;set;}
    public Guid? Related {get;set;}

    // Removed properties
    }

    This is how, under the hood, IQueryable is given to Repository’s consumer (base class inherited from DbContext, that should expose some of its features in abstracted way to Repository):
    – Set method is actually call to dbContext.Set() to get L2E queryable.

    public IQueryable Queryable(bool dalTraceable = false,
    params Expression<Func>[] includes)
    where TEntity : class
    {
    var qryWithIncludes = Set().IncludeMany(includes);
    if (!dalTraceable)
    {
    qryWithIncludes = qryWithIncludes.AsNoTracking();
    }
    return qryWithIncludes;
    }

    My intention to query db with above shown statement, that uses SelectMany method, to get specific and optionally related entities in one shot from db. Yes, I can do that in two trips to db 
    So here I am seeking some solution or workaround for this situation and found your implementation and got thinking that maybe I should take it to use.

    Br,

  40. Using this pattern, how would you get Add-Migration to automatically generate Up/Down code based off each of your POCO entities? Say I add a POCO called User. Would it automatically created the Up/Down code for the migration or is that a manual effort?

    • I see. So you still have to add public DbSet(User) Users { get; set; } to your DBContext file in the Data project. Correct?

    • Yes, you can just do it generically:

      
              public new IDbSet<T> Set<T>() where T : class
              {
                  return base.Set<T>();
              }
      
      
      
    • If I take it out, I get the following error: The entity type User is not part of the model for the current context.

      In my Context I have

      public new IDbSet Set() where T : class
      {
      return base.Set();
      }

    • Are you able to run the sample application? You may want to take a look at NorthwindContext.cs, you DbContext should have the same configuration.

    • Sounds like you don’t have the Entity mapping registered with the context? Should be in the OnModelBuilding event in your DbContext.

  41. Hi Le, I like this implementation of patterns, but I can’t use repository with my POCO’s of EF because they are not derived from EntityBase. How can I use repository in my case? Thanks.

  42. I’m getting an error on this line at UnityWebApiActivator.cs
    var resolver = new UnityDependencyResolver(UnityConfig.GetConfiguredContainer());
    Could not load type ‘Data.NorthwindContext’ from assembly ‘Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null’.

    (I’m using my own database…)
    What am I missing? Thanks in advance

  43. Le, nice work!!!

    I have one question:

    In your models (Entities) you define the relationship like:

        public partial class Product : EntityBase
        {
            public Product()
            {
                Order_Details = new List<OrderDetail>();
            }
    
            public int ProductID { get; set; }
            public string ProductName { get; set; }
            [ForeignKey("Supplier")]
            public Nullable<int> SupplierID { get; set; }
            [ForeignKey("Category")]
            public Nullable<int> CategoryID { get; set; }
            public string QuantityPerUnit { get; set; }
            public Nullable<decimal> UnitPrice { get; set; }
            public Nullable<short> UnitsInStock { get; set; }
            public Nullable<short> UnitsOnOrder { get; set; }
            public Nullable<short> ReorderLevel { get; set; }
            public bool Discontinued { get; set; }
            
            public virtual Category Category { get; set; }
            public virtual ICollection<OrderDetail> Order_Details { get; set; }
            public virtual Supplier Supplier { get; set; }
        }
    

    Ok… But why you need in the Context redefine these relationships?

        public partial class NorthwindContext : DbContextBase
        {
            public NorthwindContext() :
                base("NorthwindContext")
            {
                Database.SetInitializer<NorthwindContext>(null);
                Configuration.ProxyCreationEnabled = false;
            }
    
            public new IDbSet<T> Set<T>() where T : class
            {
                return base.Set<T>();
            }
            
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                base.OnModelCreating(modelBuilder);
    
                modelBuilder.Configurations.Add(new ProductMap());
                ...
            }
        }
    

    ProductMap:

        public class ProductMap : EntityTypeConfiguration<Product>
        {
            public ProductMap()
            {
                // Primary Key
                this.HasKey(t => t.ProductID);
    
                // Properties
                this.Property(t => t.ProductName)
                    .IsRequired()
                    .HasMaxLength(40);
    
                this.Property(t => t.QuantityPerUnit)
                    .HasMaxLength(20);
    
                // Table & Column Mappings
                this.ToTable("Products");
                this.Property(t => t.ProductID).HasColumnName("Product ID");
                this.Property(t => t.ProductName).HasColumnName("Product Name");
                this.Property(t => t.SupplierID).HasColumnName("Supplier ID");
                this.Property(t => t.CategoryID).HasColumnName("Category ID");
                this.Property(t => t.QuantityPerUnit).HasColumnName("Quantity Per Unit");
                this.Property(t => t.UnitPrice).HasColumnName("Unit Price");
                this.Property(t => t.UnitsInStock).HasColumnName("Units In Stock");
                this.Property(t => t.UnitsOnOrder).HasColumnName("Units On Order");
                this.Property(t => t.ReorderLevel).HasColumnName("Reorder Level");
                this.Property(t => t.Discontinued).HasColumnName("Discontinued");
    
                // Relationships
                this.HasOptional(t => t.Category)
                    .WithMany(t => t.Products)
                    .HasForeignKey(d => d.CategoryID);
                this.HasOptional(t => t.Supplier)
                    .WithMany(t => t.Products)
                    .HasForeignKey(d => d.SupplierID);
            }
        }
    

    Sorry if is a newbie question, I’m learning about EF recently!

  44. Hey, yes BaseRepo is my own repository with an interface. Do you mean the exception while running the test or the DbSet error inside the RepositoryQuery method?

  45. Hi,

    very very nice article to create a generic repo and the part with the unit of work. Great. But for me I have a little problem :(. First in my RepositoryQuery.cs in this line: IQueryable query = DbSet; I got this error: ‘System.Data.Entity.DbSet’ is a ‘type’ but is used like a ‘variable’.

    Second is, I use Specflowfor BDD and Moq and I want to test my generic repo, this is my code:

    http://pastebin.com/204PhJrN

    but I got this error inside the Get method:

    The member ‘IQueryable.Provider’ has not been implemented on type ‘DbSet`1Proxy’ which inherits from ‘DbSet`1′. Test doubles for ‘DbSet`1′ must provide implementations of methods and properties that are used.

    Your tutorial is the first one which has helped me until now :).

    Thx

    Chris

    • Sry, I mean inside of the Get method in BaseRepository.cs there is the error with the DbSet error: ….is a type….. not in the RepositoryQuery.cs

    • Hi Chris, thanks for the positive feedback. Is BaseRepository a class you created? Could you also paste in the code that you are trying to run when you get your exception?

  46. Thanks for your excellent post. I’m newbie to this pattern.

    I would like to know wich projects must I create in my solution when using DataBase First instead of
    CodeFirst. You have Data, Entities, Repository and Web in your Solution.
    I will not have “CategoryMap” (for ex), I will have ModelContext.tt and Model1.tt instead.
    May I merge Data and Entities project into only one?

    • Thanks flovic for the positive feedback. You should really deep you entities (POCO’s) in a separate project and this project shouldn’t reference EF if it doesn’t have to. All your ORM or EF related classes if any should be in it’s own project to address separation of concerns.

  47. I live for moments of reading blog-posts like these; well played, Sir, well played.

    I can see you’re grabbing the power tools-generated Model-folder and moving it to its own project, which is the way it should be. I was wondering if you’re in the know of a tool which would perform this step automatically? The lure of the edmx is the ‘update from database’ functionality; it would be truly terrific if it was possible to do what you, and have the projects update automatically, sans an MS build task.

    • Incidentally, I can see your Entity-project holds a reference to the Repository; I can’t get my head around if that’s desireable – could you elaborate on that bit? Thanks a million in advance.

    • Thanks harleydk for the positive feedback. Unfortunately there’s not a tool out there that I know of that automates this step with Database-First approach. Since the frequency of change for databases are typically slow changing, it hasn’t been a big deal for us to regen in another project and just copy what we need into our solution.

  48. Hi Le,

    Thanks for the wonderful article.

    I was wondering, how can I do the unit test for framework. I am curious about the repository extensions. How can you mock the methods for unit testing?

    • Hi Le,

      In the test project I can see you are faking entire Repository.

      I was just worried it may take long if i have more than 100 entities and most of the repositories needs extension. Do you have any other suggestion or reflection idea to retrieve a custom repository from the UoW?

      something like if I ask for UoW.Repository() can retrieve IEmployeeRepository instead of IRepository

    • Hi Sanu, could you elaborate a bit more on what the differences are between an extended e.g. IRepository vs. IEmployeeRepository?

    • Hi Le,

      Here is my scenario. I am also using similar pattern in our project but bit different. I have a generic Repository which implements the basic CRUD operations an when I need a custom query I create a custom Repository inheriting the Generic Repository.

      IEmployeeRepository : IRepository
      {
      IEnumerable GetActiveEmployees();
      }

      EmployeeRepository : GenericRepository , IEmployeRepository
      {
      public IEnumerable GetActiveEmployees()
      {
      //some query
      }
      }

      And in my Service layer I use UoW and calling the Employee Repo methods.

      EmployeeService
      {

      public bool SomeMethod()
      {
      var activeEmps = _uow.EmployeeRepository.GetActiveEmployees();
      }
      }

      Now when I do the unt test I can fake IEmployeeRepository and Stub GetActiveEmployees method but If I use your pattern I can only Fake IRepository this class don’t have the GetActiveEmployes method. So It will be calling the extention method and I have to Setup values to execute via extension methods.

      I believe it’s not possible to Fake Static classes. So I was looking for a way to retrieve IEmployeeRepository from the UnitOfWork insted of IRepository.

  49. Hey Le,

    nice work!

    I’m trying to use a paged stored procedures with latest build, but seems I can’t get an output parameter with total records. Also, after I updated EF from 5 to 6 I got an “.The property ‘XXX’ on the type ‘YYY’ has a property type of ‘System.Data.Spatial.DbGeography’ which cannot be mapped to a primitive type.”

    Do you have any idea what’s going on?

    Thanks!

    • Thanks Ruben for the positive feedback, I’m not sure why you are getting these issues, however these are all EF related issues and not related to the Framework. All we’ve done is expose the Sql method so you can execute SQL/SPROCS.

  50. Question:
    Where can I find the hotfix for this problem? Yes we do, we’ve already put a hot fix out there under the “main” branch. (Commented October 30.)
    Original question was:
    We were experiencing a very similar problem, except we would see the duplicates any time we used the context more than once in the life-cycle of the page. Our proposed fix it to modify the changes methods as such:

    Thanks for a really good framework!

  51. _unitOfWork.Repository().Update(player);

    doesn’t work ,

    I added DbEntityEntry Entry(object obj); to and IDbContext and using like this :

    _unitOfWork.Entry(playerEventRow).State = EntityState.Modified;;
    _unitOfWork.Save();

  52. Sorry don’t know what happened with my cut and paste! But I had set the repo to Em,ployee using:

    public ActionResult Index()
    {
    var employee = _unitOfWork.Repository().Query().Get();
    return View(employee);
    }

    Just don’t get why it pulls no data.

    I get a strange error message:

    The column name is not valid. [ Node name (if any) = Extent1,Column name = TitleOfCourtesy ]
    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: System.Data.SqlServerCe.SqlCeException: The column name is not valid. [ Node name (if any) = Extent1,Column name = TitleOfCourtesy ]

    Source Error:

    Line 32:
    Line 33:
    Line 34: @foreach (var item in Model)
    Line 35: {
    Line 36: @item.FirstName, @item.LastName

    I use this to display the data it should pull:

    @foreach (var item in Model)
    {
    @item.FirstName, @item.LastName
    }

    weird I say! If my copy paste has worked correctly!!

    • I don’t think you are running SQL Server CE, so you need to update your EF provider in your config file to probably SQL Server or SQL Server LocalDb. And also check your entity and/or entity mappings, looks like you might not have a field or column named TitleOfCourtesy.

  53. Hi Le! Excellent post!

    Please bear with me, I am very new to this and am learning all the time. Your implementation is quite elegant I think and what I have been trying to achieve whilst learning about repository design!

    I am struggling to understand though how I would seed a database using this method? Will you be doing a blog post that includes Migrations and EF?

    I would usually something like:

    var people = new List
    {
    new Division { Name = “Gareth”, Title = “Mr” },
    new Division { Name = “Le”, Title = “Mr” },
    };

    people.ForEach(s => context.Person.AddOrUpdate(p => p.Name, s));
    context.SaveChanges();

    How would I use your method to complete this?

    • Hi Le,

      Not sure how this is going wrong but using the latest download from CODEPLEX I have added the following code to the home controller:

      private readonly IUnitOfWork _unitOfWork;

      public HomeController(IUnitOfWork unitOfWork)
      {
      _unitOfWork = unitOfWork;
      }

      protected override void Dispose(bool disposing)
      {
      _unitOfWork.Dispose();
      base.Dispose(disposing);
      }

      public ActionResult Index()
      {
      var employee = _unitOfWork.Repository().Query().Get();
      return View(employee);
      }

      This though returns employee as being completely null??? I have checked the database and it definitely has the employees in it. Am I doing something wrong?

  54. How would I do an .Include on an inner object that is a collection. For example. I have and Order object, that order object has a Collection of OrderLines and each OrderLine object has a Product object.

    I can get the first part to work.

    UnitOfWork unitOfWork = new UnitOfWork();
    List orders = unitOfWork.Repository()
    .Query()
    .Include(l => l.OrderLines).Get()

    When I try an include the Project table its not available.
    .Include(l => l.OrderLines.Product)

    because OrderLines is a collection of OrderLine entities and not a single entity I’m not able to get at Product entity.

    Any suggestions?

    • Actually I just figured it out.

      .Include(l => l.OrderLines.Select(c => c.Product))

      That seems to work and returns the Product entity for each of the OrderLines in the Collection.

      regards, Scott

      FYI.. Awesome framework!!!

    • Hey thanks Scott for posting this solution you found, I was having the same issue.

      And I agree, nice framework and documentation provided on this blog – thanks very much Long Le for your efforts.

  55. Good afternoon Le,

    One more question for you (I hope).

    1. When calling _unitOfWork.Repository().InsertGraph(new Entity.Models.User()); I don’t see where the entity (a User in this case) or its linked entities (address(es), phone number(s), etc.) are getting an ObjectState set to Added. I note that we manually perform this action in the Insert(TEntity) command (Line 98 in the v2.0 of Repository.cs). What am I missing?

    Thanks much!

    • Nevermind, Le. I see your response on 10/13 that recommends you explicitly set the state on new objects (I was seeing the state set inside the Insert(TEntity), and thinking it would apply to InsertGraph as well). As soon as we manually set ObjectState to Added on our new entities, everything works as expected.

      Thanks!

  56. Nice article. How do you take care of returning the auto increment column values that are returned by the DB server (say Identity column in SQL server)? For example in the Order-OrderDetails use case, if the requirements are to add the Order and OrderDetails in single transaction and OrderID is Identity column and its value is needed in each of the OrderDetails rows.

    • You would only need to set the IObjectState explicitly for Order and OrderDetails e.g. Order.State = ObjectState.Added, and for each of the OrderDetail(s), EF will handle the rest. Explicitly setting the State for any entity is pretty much a rule when using the framework.

  57. Good morning Le,

    Thank you for an excellent article. It has very much helped me get a view of what I want to implement. I do have a couple of questions for you:

    1. Is the Unit of Work (UoW) pattern worth the added complexity to the project (esp. with regards to having it somewhat already implemented through EF)? I feel like it is, but am having a hard time verbalizing why I feel that way, and wanted to get your thoughts.

    2. It feels wrong to have the EF assemblies referenced in our IDbContext interface… Have you or any of your followers come up with a good way to extract that out to only be referenced in the Data assembly?

    Thanks much!

    • Hi Brad, thanks for the positive feedback.

      1. The UoW pattern is suppose to help with shielding the developer from some of the complexities of knowing all the ins and outs EF e.g. managing entity graphs when inserting or updating them. It’s also there so that you don’t need EF referenced in our presentation layer e.g. ASP.NET MVC, we have it referenced only because Unity (DI & IoC) need so we can register the binding between NorthwindContext and IDbContext. The next version this will be completely removed and we will let each of their projects manage their own Unity Registrations, right now the Web App is handling all of this. Other than that there is not code in the presentation layer that depends on EF.

      2. Our first objective was having no dependencies on EF in our presentation layer, perhaps we look at further pushing EF to only be referenced in the Data project, for the next version as well, thanks for the request.

  58. Hi Le, Me again. I could not find where you reset your entity’s ObjectState after persisting the data changes. So I assume you don’t. If that assumption is correct, was that intentional?

    • And as a follow-up, why not just update EntityState directly? Thanks very much again for your help.

    • Could you elaborate a bit more on “directly”? Because if it’s dealing with a single entity on insert or update that’s fine but we give up on entity graphs and that’s not something we want. The optimal and easiest way without requiring the developer to understand and intimately know the different combinations and permutations of how EF deals entity graphs is to let the developer explicitly set this on each entity.

    • That’s actually a good catch, hasn’t been a problem for us yet, since we’re always explicitly handling State, meaning when we’re explicitly setting the entities State before every time before calling Save again. Please share your solution, we may incorporate it back into the framework!

    • Hi Le,

      Here’s what I did:
      – I’m not using the InsertGraph. And since the only time I need to tell EF the state of an entity is during an Update, I created a method on the DbContext whose sole purpose is to mark an entity as Modified.
      – From my generic repository, I call that DbContext method from the Update(), right after Attach().

      However, if I use the InsertGraph(), I think this solution will work instead:
      – On the ApplyChanges, I simply add a line that changes the entities ObjectState property to Unchanged, after the ConvertState().

      Thanks
      Frank

    • -Although we recommend that the State be explicitly set, we are automatically setting the root entity when performing an insert or update in the latest version of the framework (v2.0). Is this what you are doing in your mention of “method on the DbContext whose sole purpose is to mark an entity as Modified”?

      
      public virtual void Update(TEntity entity)
      {
          _dbSet.Attach(entity);
          ((IObjectState)entity).State = ObjectState.Modified;
      }
      
      public virtual void Insert(TEntity entity)
      {
          _dbSet.Attach(entity);
          ((IObjectState)entity).State = ObjectState.Added;
      }
      
      

      -For the ApplyStateChanges, we will go ahead and add that as a WorkIem to reset the all the entities in the graph, after Save() has been called, thanks for the pointing this out.

    • Le,

      This is the method I added in the DbContextBase. It is actually an idea I took from Kazi Manzur Rashid’s blog about Generic Repositories:

      public void MarkAsModified(Tentity instance)
      where Tentity : class
      {
      Entry(instance).State = System.Data.EntityState.Modified;
      }

  59. Pingback: Lindermann's Blog | Excelente Material Sobre Implementação de MVC com Entity Framework

  60. Pingback: MVC 4, Web API, OData, Entity Framework, Kendo UI, Binding a Form to Datasource (CRUD) with MVVM – Part 3 | Long Le's Blog

  61. Pingback: MVC 4, Kendo UI, SPA with Layout, View, Router & MVVM – Part 1 | Long Le's Blog

  62. Pingback: Upgrading to Async with Entity Framework, MVC, OData AsyncEntitySetController, Kendo UI, Glimpse & Generic Unit of Work Repository Framework v2.0 | Long Le's Blog

  63. Hey Le,
    I’ve been an ardent reader of all your posts. Brilliant stuff!
    However, I’ve had 2 questions which have been niggling me for a while now and I haven’t found a satisfactory response for them.
    1] What’s the advantage of using the EF, if I have a db. where all the stored procedures are already defined?
    2] As far as the repository pattern goes, everything I have read/seen so far has 1 repository for 1 entity .i.e. a 1:1 relationship. In this case, what happens if the business layer needs results that span across entities – inner/left/outer join. In which repository would this API live?

    • 1. EF is an ORM does alot of the heavy lifting of mapping the data from SQL database into your objects/classes/entities, obviously this is an extremely over simplification on what EF’s capabilities are, but the net answer is it makes the communication/interactivity between your app and your database much easier.

      2. It should live in what ever repository that makes the most logical sense to you, this is very subjective and you become better at making decisions with experience. When you use EF, you can access all the other entities that are associated to it e.g. Customer.Orders.OrderDetails, etc. Now if you need access to entities that are not associated, then you need to create a sevice e.g. ICustomerService and inject IUnitOfWork into so that you can access whatever you need. Repositories are usually very focused on the entity at hand for separation of concerns, organization and manageability.

  64. Hi Le,

    Thanks for your detailed post. This is probably a silly newbie question: why do you have the EntityBase class in your Repository project? Wouldn’t it make more sense to put it in Entity since all (or most of) your POCOs derive from it? Same goes with ObjectState and IObjectState

    • Great question…! We deliberately placed EntityBase in the Repository layer/project to make the framework portable. Meaning I can add easily add the Repository project into any solution and immediately be up and running with the UoW and Repo framework (Repo is completely decoupled from Entity) .If we were to have EntityBase in the Northwind.Data project (which would now make Repo and Data coupled, which we don’t want), which are really domain entities that are specific and coupled to an application, we would have to remember to add the EntityBase separately every time. Some of the design principles were re-usability, portability (plug-in play), easiability (plug-in play), modularity, and scalibility (ability to scale this framework across any time of application (ASP.NET Web Forms, ASP.NET MVC, WPF, Silverlight, Windows Service, WCF, etc.).

  65. Pingback: Reading Notes 2013-09-30 | Matricis

  66. Pingback: Reading Notes 2013-09-29 | Matricis

  67. Absolutely brilliant post.
    I just got a error trying to run the program.
    In the NorthwindContext it says it cant find DbContextBase and IDbContext.
    That is also resulting in error in the constructor and the base.Set

    Hope you can help
    Jakob

  68. Hi, first let just say that this article it’s a must have in the bookmark list of every .net developer great great article.
    I have a question, what I should do if I want to join several entities inside a repo, i notice that using an extension methods on the Interface was the way but how can i access other entities ??

  69. Hey There. I found your blog using msn. This is a really
    well written article. I’ll be sure to bookmark it and return to read more of
    your useful info. Thanks for the post. I’ll definitely
    comeback.

  70. I am having an issue. When I insert an object say ‘Customer’ I get an error Invalid column name ‘State’. I have set the state property to be added in my instance of customer object. When I don’t add the state = added then the entity state remains unchanged and

    • I am having an issue. When I insert an object say ‘Customer’ I get an error Invalid column name ‘State’. I have set the state property to be added in my instance of customer object. When I don’t add the state = added then the entity state remains unchanged and nothing gets inserted into the database.

    • You need to decorate the State property with the [NotMapped] attribute or you can specify this property to be ignored by configuration.

      public class Customer
      {
          public int CustomerID { set; get; }
          public string FirstName { set; get; } 
          public string LastName{ set; get; } 
          [NotMapped]
          public int Age { set; get; }
      }
      

      or

      
      protected override void OnModelCreating(DbModelBuilder modelBuilder)
      {
         modelBuilder.Entity().Ignore(t => t.LastName);
         base.OnModelCreating(modelBuilder);
      }
      
      
  71. Hi,

    First of all i’d like to thank for this great post. Well, it seems that i have some problems running the above code.

    I’ tried to test the above code; so i added a custom model CustomModel and inserted the following lines of code into my controller:

    var uof = new UnitOfWork(new CustomContext());
    var repo= uof.Repository();
    repo.InsertGraph(new CustomModel());
    uof.Save();

    var list = repo.Query().Get().ToList()

    The last line throw an exception:

    Invalid object name ‘dbo.CustomModel’

    The error makes sense because in the “Server Explorer” in visual studio i cannot see any table named CustomModel

    Can you tell what i’m doing wrong?

    Cheers.

    • You should only be using models that are from Entity Framework (POCO’s). I’m not sure if CustomModel is a true Entity Framework POCO but it doesn’t sound like it. You cannot just simply pass in any random C# object and expect the UoW and/or Repo framework and assume that it will know how to persist this to your database.

    • I do use migrations and i do make Update-Database but the problem is that when i then try to call WebSecurity.InitializeDatabaseConnection(“connectionString”, “UserProfile”, …) to create the WebMatric tables, it throws an exception saying that the userProifle table doesn’t exist

  72. Pingback: Lindermann's Blog | Implementação dos padrões UoW e Repository com Entity Framework

  73. Pingback: Dew Drop – September 17, 2013 (#1,625) | Morning Dew

  74. Hi.. If i want to Override FindById for a Entity in the UnitOfWork scope, how can i do that.
    I tried the following code, but this method will never be hit.

    public class ProductRepository : Repository, IRepository
    {
    public ProductRepository(IDbContext context)
    : base(context) { }

    public override Product FindById(object id)
    {
    return base.FindById(id);
    }
    }

  75. I just wanted to give feedback on my experience using the Entity ObjectState implementation above. I ran into an issue with Seeding the DB with EF (using the Configuration.Seed method). In simple terms, if you use the overrided SaveChange method that contains the this.ApplyStateChanges() method, you will run into issues with duplicate rows being added to the database.

    The work around is found in this post on stackoverflow: http://stackoverflow.com/questions/10007351/entity-framework-code-first-addorupdate-method-insert-duplicate-values/17913036#17913036

    I don’t understand why this happens, and would really like to read an explination. To solve I add another method called SaveSeedChanges() without the ApplyStateChanges — and it works fine.

    Hope this helps!

    • Appreciate the update aadamxs, this will be helpful for all of us that are doing code-first, including myself.

    • Good evening all,

      We were experiencing a very similar problem, except we would see the duplicates any time we used the context more than once in the life-cycle of the page. Our proposed fix it to modify the changes methods as such:

      public void MarkEntitiesAsUnchanged()
      {
      foreach (DbEntityEntry dbEntityEntry in ChangeTracker.Entries())
      {
      var entityState = dbEntityEntry.Entity as IObjectState;

      entityState.State = ObjectState.Unchanged;
      }
      }

      public override int SaveChanges()
      {
      ApplyStateChanges();

      int baseReturnVal = base.SaveChanges();

      // If we modified any records, set their state back to Unchanged
      if (baseReturnVal > 0)
      MarkEntitiesAsUnchanged();

      return baseReturnVal;
      }

      Do you (or your loyal readers) see anything glaringly wrong with such a modification?

      Thanks much!

    • Morning Le,

      We have implemented your hot fix on our code, and are compiling successfully. I am having an issue now with bindings to multiple contexts in one project. We are currently using Ninject for our DI container, and before, we were able to bind the appropriate context based on T-Types:

      Bind<IUnitOfWork>().To<UnitOfWork>();
      Bind<IUnitOfWork>().To<UnitOfWork>();

      After the implementation, we are struggling with appropriately instructing Ninject as to what Context we need on a per-controller basis (we are using the framework in an MVC / WebAPI project). How would you suggest differentiating which IDbContext gets injected into the IUnitOfWork assembly?

      Thanks much!

    • No problem, last but not least, make sure you guys test that each of the UnitOfWork(s) instance lifecycle is bound to the HttpRequest lifecycle. Meaning, they should all have Singleton behavior for the current user through the HttpRequest. We’ve deliberately left the InstanceId property on the IUnitOfWork, IRepository and IDbContext so you can test this with which ever DI/IoC framework you are using.

    • Hi Le,

      I still got duplicates as what mrbaseball2usa mentioned. I am using the latest change set: 27965 (Nov 3 3:32 PM). Does change set 27965 include your hot fix?

      Best wishes,
      Fan

    • Hi Fan, we will check – in a change set first thing in the morning (CST) with this fix, thx for you patience, will update you as soon as it’s checked in.

  76. Would it be possible, somehow to support Select? I mean, just to select some columns/properties instead of the whole TEntity.
    Sometimes this is useful when dealing with complex types just to take the properties you need instead of the whole object graph.

  77. Thanks again for your responses. As you indicated, removing the reference and moving the configuration worked as you said it would. As you also touched on, whether or not we want to take that step for a very strict separation is now something we can decide on as either approach will work. It’s nice to have the choice.

    Your code has been very helpful!

  78. Hi Le. I’m a bit confused here and I wonder if you could help clarify. As you say above, “…our presentation layer…should not have any dependent code on EF assembly, therefore that should not be any references to the EF assembly, it should only reference our Repository project for data access.”

    However, I have downloaded your sample code and I see that the Spa project does in fact reference the Entity Framework library:

    False
    ..\packages\EntityFramework.5.0.0\lib\net45\EntityFramework.dll

    Can you clarify for me why that is and if I’m missing something or just confused?

    Thanks,
    Andy

    • Good question, the assembly has been added as a reference so that it gets copied to the bin folder because the connection string for EntityFramework in the web.config requires the assembly for the sql provider. However, we don’t have any actual code in the application that is dependent on EntityFramework. All data access happens through the IUnitOfWork and IRepository. Also, there is no EF dependencies in the Entity project as well, where are the POCO entities reside, which there shouldn’t be, since they are actually plain old vanilla C# objects.

      Connection String Example (providerName attribute requires the EntityFramework assembly):

       
      <add name="NorthwindContext" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=Northwind;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\Northwind.mdf" providerName="System.Data.SqlClient" />
       
      

      You can create a folder named “Assemblies” add the EntityFramework.dll and the EntityFramework.SqlServer.dll to it, set the “Build Action” to “Content”, set the “Copy to Output Directory” to “Copy Always” and remove these references from your project.

    • Thanks for the fast response, Le. But, I’m still having problems.

      I went ahead and removed the EntityFramework reference from the Spa project. I also removed the AccountController and the other SimpleMembership files as they also reference EF directly and are not relevant to what I’m trying to do at the moment.

      However, when building your solution (and mine, which is modeled after it), I receive the following error in the Bootstrapper:

      The type ‘System.Data.Entity.DbContext’ is defined in an assembly that is not referenced. You must add a reference to assembly ‘EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089′.

      This error is tied to line 25 which is the line where the NorthwindContext is registered, i.e., container.RegisterType();

      The NorthwindContext object is derived from DbContext, which is in the EF library.

      Thanks!
      Andy

    • Aaah, yes, Unity needs this for DI & IoC. We would have to remove the registration for IDbContext from UnityConfig.cs and move the registration to the web.config.

    • Honestly, I wouldn’t let that bother me, the reference is there only because Unity requires it for Registration for DI & IoC, there’s no actual code in our application that uses Entity Framework directly for data access, which is what the objective is.

  79. Hello Le,

    Very good article!

    I’ve got a question for you:

    Have you got some generators for the entities classes? Because if you’ve 40/50/80 tables…and you need to have all the classes about this tables in your solution, do you use some generator for the entities? and mapping?

    Keep up with good job!

    Regards.
    CM

    • Thank you so much for quick answer!

      Last question ( lol ):

      I don’t know if you use stored procedures in your solutions, but in case that you have to call some stored procedures, what could be the best practice for that?

      Regards,
      CM

    • You can extend the UnitOfWork add add a method StoredProcedure<T>, the type that you pass in could be the Model that EF generates for the StoredProc when using EF Power Tools. EF Power Tools will generate Tables, Views, SPROCS, etc.

    • Hi Le,

      Again I’d like to echo your work at bringing it all together so nicely. I’ve already implemented most of this work, but am getting slightly unstuck when it comes to writing in the Stored Procedure part in. Could you elaborate on an example please? I just don’t know how to get my EF UoW to run the SP and return in the complex object type that I’ve got via using DatabaseFirst.

      private readonly IDbContext _context;
      public IList StoredProcedure(object[] parameters) where TModel : class
      {
      return null;
      }

      Any help?

      Thanks.

    • Hi Matt,

      Thanks for the positive feedback, we are releasing v2.0 of this framework this weekend, it will support sprocs.

      For now you can see it @ : https://genericunitofworkandrepositories.codeplex.com/SourceControl/latest#main/Repository/Repository.cs

      
              public virtual IQueryable<TEntity> SqlQuery(string query, params object[] parameters)
              {
                  return _dbSet.SqlQuery(query, parameters).AsQueryable();
              }
      
      

      You would call it this way:

      
      _unitOfWork.Repository<Customer>().SqlQuery("sp_MyStoredProc @firstName, @lastName", param1, param2);
      
      

      If you want you can go ahead and download what’s in the main branch, it’s in beta though.

    • Hi Le,

      Thanks for the speedy reply. The solution you’ve posted is what I’ve got already and I feel a little unsettled at exposing EF to SQL input by any developer. The solution I’ve coded is very generically so that I am exposing via interfaces and base classes only what I want them to use. I have the repository pattern and unit of work going on, but also have a layer in between the business logic and EDMX which takes in the unit of work and sets up a new repository and context for each POCO. It means that one unit of work is getting thrown about in the business logic and recording loads of changes instead of just one graphs changes.

      Guide:

      http://stackoverflow.com/questions/15181290/decouple-unit-of-work-from-services-or-repo/15527444#15527444

      However, this has led me to my stored procedure issue. I want to be able to import my SP into DatabaseFirst, create my DAL-ish layer and call the SP. Normally I (literally) call Repository.GetList as I pass in the type genrically and it handles the rest, so I want something just as simple.

      Was that a load of waffle or does that make sense?

      Thanks

    • Hmm, interesting, haven’t had a use case for this particular scenario, however if you come up with an elegant solution, please do share. :)

  80. Hi Guys,

    As I’ve got it cracked just wanted to give you a head around the reason I was facing the issue

    In the following code even though All property is an IQueryable I was getting it in an IEnumarable mylist which make the Entityframework build the object graph for 2 Million records which is causing the An exception of type ‘System.OutOfMemoryException’.
    The work around was to get the IQuearyable and filter the result set on service layer or get the RepositoryQuery return IEnumarable just in case the reult set is filtered.

    public MyPOCOClass GetByNumber(string myClassNumber)
    {

    IEnumerable mylist ; // wrong leave it as var which will return IQueryable

    MyPOCOClass item ;
    using (UnitOfWork uow = new UnitOfWork())

    {
    IRepository repo = uow.Repository();

    mylist = repo.All;

    repo.FindById(2023182); //Works fine

    var itemlist = from i in mylist
    where (i.ClassNumber==myClassNumber)
    select i ;
    item = itemlist.FirstOrDefault();
    }

    return item;
    }

    On Generic Repository:

    public IQueryable All
    {
    get { return Context.Set(); }
    }

  81. Hey, this is a great post i have learned a lot. I have a question i have an object that has a child list of object and when i send them to update to the repository im recieving a constration error like this:

    {“An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.”}

    How can i fix this problem when updating entities with child items.

    Regards,

  82. Hi Le ,

    Thanks for the great post.
    It is really one of the best :)

    I’m using this framework for my project in which we have more that 100 tables. for small proof of concept with let’say 20 tables it worked perfectly fine though when I wanted to just scale this up for the big database which effectively have big object graphs I got the Out of Memory exception when using following pattern
    from my controller

    UnitOfWork.Repository.Query().Get()
    However
    UnitOfWork.Repository.FindById(id) works perfectly fine .

    I’m using EF 5 with .NET 4.5 VS 2012

    Am I missing some part ?

    For simplicity following is the code

    on my client app

    public MyPOCOClass GetByNumber(string myClassNumber)
    {

    IEnumerable mylist ;
    MyPOCOClass item ;
    using (UnitOfWork uow = new UnitOfWork())

    {
    IRepository repo = uow.Repository();

    mylist = repo.All;

    repo.FindById(2023182); //Works fine

    var itemlist = from i in mylist
    where (i.ClassNumber==myClassNumber)
    select i ;
    item = itemlist.FirstOrDefault();
    }

    return item;
    }

    On Generic Repository:

    public IQueryable All
    {
    get { return Context.Set(); }
    }

    And on Unit of Work:

    public IRepository Repository() where T : class
    {

    //Repository r = new Repository(_context);
    //return (IRepository)r;

    var repositoryType = typeof(Repository);

    var repositoryInstance =
    Activator.CreateInstance(repositoryType
    .MakeGenericType(typeof(T)), _context);

    return (IRepository)repositoryInstance;
    }

    I have exposed the IDbSet through All property as I thought I may have missed something to do with
    Repository hash table or Query method or Get method and simply I’m not using them to locate the issue though no chance :(

    Here is The Exception:

    An exception of type ‘System.OutOfMemoryException’ occurred in System.Data.Entity.dll but was not handled in user code

    Stack Trace:

    at System.Collections.Generic.Dictionary`2.Resize(Int32 newSize, Boolean forceNewHashCodes)
    at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
    at System.Data.Objects.ObjectStateManager.AddEntryToKeylessStore(EntityEntry entry)
    at System.Data.Objects.ObjectStateManager.AddEntityEntryToDictionary(EntityEntry entry, EntityState state)
    at System.Data.Objects.ObjectStateManager.AddEntry(IEntityWrapper wrappedObject, EntityKey passedKey, EntitySet entitySet, String argumentName, Boolean isAdded)
    at System.Data.Common.Internal.Materialization.Shaper.HandleEntityAppendOnly[TEntity](Func`2 constructEntityDelegate, EntityKey entityKey, EntitySet entitySet)
    at lambda_method(Closure , Shaper )
    at System.Data.Common.Internal.Materialization.Coordinator`1.ReadNextElement(Shaper shaper)
    at System.Data.Common.Internal.Materialization.Shaper`1.SimpleEnumerator.MoveNext()
    at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
    at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
    at

    which is happening on GetByNumber(string myClassNumber)

    I know that this could be confusing, though I really appreciate it if you can share some thoughts or guideline

    Cheers,

    • A.T, hmmm, strange, quite a few teams are using this in production with fairly large databases (tables) with a lot data throughput. Are you using in DI & IoC, if so, may be an issue with the lifetime management, if you are, which framework are you using? If not, is the UnitOfWork have singleton like behavior? Also, what kind of app is this in (e.g. MVC, WPF, WCF)?

  83. ah ha, never mind, I figure it out.. after call the first OrderBy, immediately call OrderByDescending.

  84. Hi this is an awesome post. very clean! not like other articles that extending IRepository and creating concrete implementation which is very time consuming and you have to touch the UnitOfWork everytime you have to add a repository because Repositories are members unlike with your design that they are automagically created.

    I just have a question because youve mention “to abstract away ORM tool like EF” but in your IDbContext you have a method that returns IDbSet which is under the EF assembly. what if I use other ORM? can I implement that method?

    • Thanks Daskul for the positive feedback. Yes there was some deep thought around “Open and Close” principle when designing and implementing the generic Unit of Work and Repository. In theory, yes you should be able implement this generic Unit of Work and Repository Pattern with any ORM, however when doing so there maybe a few very minor changes, e.g. wrapping the other ORM’s version of DbSet.

    • thank you for your quick response.

      does it mean I still have to reference EF when using other ORM?

      and I have another question, where should the Extension Methods live? in the Repository assembly? and isnt it RepositoryQuery is just like exposing an IQueryable on client? what is the difference between the two? why not just provide extension methods and no more query?

  85. Hello!

    This is a fantastic post. I am glad I stumbled across it. I have previously implemented solutions using SharpArchitecture, however, I wanted to get away from the reliance on its framework in order to get a better understanding of the Repository pattern and UoW in an MVC3/4 solution.

    I downloaded your sample solution (linked by this post) and am attempting to use your bits with Castle.Windsor, although seeing how easy it is implementing Unity now, I might switch.

    I have two questions.

    Firstly, I didn’t see anywhere in your sample solution where the DbContext was being created and disposed in the lifetime of a Request. Is this handled internally in Unity? Am I missing something obvious? I’ve been accustomed to using NHibernate, so EF is a bit new for me.

    Secondly, I am curious about some of the references in each assembly. I noticed the Repository assembly references several System.Web assemblies, but it appears to only be relying on System.Web.Mvc which looks like it points to the DependencyResolver in the Bootstrapper. Would it be better if the Bootstrapper implementation lived in the web project (Spa)?

    Thanks again for a great series of articles!

    • Thx, for the positive feedback Jonathan.

      Unity v3.0 is awesome, I’d make the switch :)

      Answer 1:

      If you view this post: Bounded DbContext with Generic Unit of Work, Generic Repositories, Entity Framework 6 & EntLib Unity 3.0 in MVC 4 and scroll down to the section titled: Spa.App_Start.UnityWebActivator.cs, this is where we default everything’s lifecycle to the lifecycle of the request.

      Answer 2:

      I’m working on uploading v2.0 of this solution that has optimizations to DOM management (letting Kendo manage all of this), View caching improvements, and uses WebActivator vs. BootStrapper (which I thought this solution was already using), and much more ASP.NET MVC developer friendly (based on MVC dev community feedback). Hoping to upload it before the weekend is over, I’ll update the blog series when its uploaded.

  86. Hi Long,

    I keep coming back to your blog from google. And I must say, it’s one of the easier to understand explanations of setting up repositories and units of work, etc that I’ve come across. I’m an 8th grade teacher here in Southern California, and trying to learn programming over the summer to build a better way for students to learn. Question I have is I want to use bounded contexts as my database will grow with more tables, and it makes sense to me. Julie Lerman suggests using using a separate unit of work for each dbcontext. But when setting up the concrete units of works in IOC, how would structuremap know which concrete unit of work to use? I can have IUnitOfWork uow and the whole point is that structuremap knows which concrete instance to pick up — easy if there’s just one, but how would structuremap know which one to inject in an mvc4 application when you potentially have 5 different dbcontexts, etc. You’d think it’d be confused, and I really want to use bounded contexts, and IOC at the same time. Thank you,

    Tim

  87. internal IDbContext Context;
    internal IDbSet DbSet;

    assembly not found for both the interfaces.
    to avoid this error i need to copy your interfaces which is in your Data layer.
    But the actual change here is that i have to modify my context class to implement the interface.
    public class NorthwindContext : DbContext, IDbContext
    {
    }

    since you are using the code first approach its fine to modify it. but in my case the NorthwindContext is automatically created by using db first approach and it extends DbContext only and any change to this NorthwindContext will be automatically deleted when i run the command update model from database which is provided by the EF.

    i hope its clear for you.

    thank you

    • Can you manually re-apply your DbContext over the generated one after your update? or you just create a partial class for the NorthwindContext?, or create another abstract custom DbContext (NorthwindContextBase) which would inherit DbContext e.g. NorthwindContext -> NorthwindContextBase (abstract) -> Dbcontext (abstract)?

    • BTW, why don’t you just simply delete the generated one? The DataContext in this post is “Generic” meaning you never have to to update it, no matter how many new models are added, deleted or modified, because you access them by Repository<Customer>(), meaning, just ignore the generated one, you don’t even need it.

  88. hi
    i’m using the db first approach for EF, This is how my Context class is. its auto generated and i cannot modify it. coz it will get re-generated even if i modify it.

    i’m getting error in the Repository class at this location….pls help, i liked your tutorial, but i’m stuck now :(

    public class Repository : IRepository where TEntity : class
    {
    internal IDbContext Context;
    internal IDbSet DbSet;

    some code to follow……….
    }

    public partial class ORPEntities : DbContext
    {
    public ORPEntities()
    : base(“name=ORPEntities”)
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
    throw new UnintentionalCodeFirstException();
    }

    public DbSet Addresses { get; set; }
    public DbSet DataDictionaries { get; set; }
    public DbSet Documents { get; set; }
    public DbSet EmployerDetails { get; set; }
    public DbSet EmployerInEventsInJobs { get; set; }
    public DbSet Events { get; set; }
    public DbSet Jobs { get; set; }
    public DbSet Memberships { get; set; }
    public DbSet OAuthMemberships { get; set; }
    public DbSet Roles { get; set; }
    public DbSet SelectionCodes { get; set; }
    public DbSet SelectionProcesses { get; set; }
    public DbSet sysdiagrams { get; set; }
    public DbSet TaskManagers { get; set; }
    public DbSet UserEducationDetails { get; set; }
    public DbSet UserInJobs { get; set; }
    public DbSet UserITSkills { get; set; }
    public DbSet UserPersonalDetails { get; set; }
    public DbSet UserProfiles { get; set; }
    public DbSet UserResults { get; set; }
    public DbSet UsersInRoles { get; set; }
    public DbSet UsersInTasks { get; set; }
    public DbSet UserWorkExperiences { get; set; }
    }

  89. I stumbled across this blog while looking for MEF, EF, UOW and how they interact. This blog is a treasure trove of data. Fantastic job on putting it together Le!

  90. Hi Le

    I was looking for a generic implementation of the Unit of Work and Repository patterns when I came across your blog. It has helped me immensely and I appreciate that. In the intial blog about implementing the patterns you talked about extending the IRepository interface for specific objects.

    I’m trying to implement that and had assumed that I should call the extension method in this form:

    IUnitOfWork.Repository().ExtensionMethod();

    However Visual Studio complains that IRepository does not contain a definition for ‘ExtensionMethod’ and no extension method ‘ExtensionMethod’ accepting a first argument of type IRepository could be found.

    My IRepository interface, implementation and the static class containing the extension methods all share the same namespace so it shouldn’t be a reference issue. My static class is defined as:

    public static class ExtensionClass
    {
    public static SpecificEntity GetSingleEntity(this IRepository seRepository, int id)
    {
    }
    }

    Am I calling the extension method in the correct manner? Do you see any other potential issue in the code?

    • Oops, apparently the copy and paste from the email upset a few things: The call I’m making is

      IUnitOfWork.Repository().ExtensionMethod();

      and the function is

      public static SpecificEntity GetSingleEntity(this IRepository seRepository, int id)

      Thanks

    • Ok, sorry for the chain of comments. It’s WordPress seeing my template declarations as a tag. Guess I shoudl have put it in a code section

      Call:

      IUnitOfWork.Repository().ExtensionMethod(id);

      Function:

      public static SpecificEntity GetSingleEntity(this IRepository seRepository, int id);

    • Hi Richard,

      It’s best practice to have the extension method this way:

      (example)

      
      public static class CustomerRepository
      {
          public static void AddCustomerWithAddressValidation(
              this IRepository<Customer> customerRepository, Customer customer)
          {
              USPSManager m = new USPSManager("YOUR_USER_ID", true);
              Address a = new Address();
              a.Address1 = customer.Address;
              a.City = customer.City;
       
              Address validatedAddress = m.ValidateAddress(a);
       
              if (validatedAddress != null)
              customerRepository.InsertGraph(customer);
          }
      }
      
      

      Notice in the example the extension method is extending (first parameter)

      
      this IRepository<Customer> customerRepository
      
      

      Reason is, in the UnitOfWork implementation we are actually returning IRepository<T> .

      
              public IRepository<T> Repository<T>() where T : class
              {
                  if (_repositories == null)
                      _repositories = new Hashtable();
      
                  var type = typeof (T).Name;
      
                  if (!_repositories.ContainsKey(type))
                  {
                      var repositoryType = typeof (Repository<>);
      
                      var repositoryInstance = 
                          Activator.CreateInstance(repositoryType
                                  .MakeGenericType(typeof (T)), _context);
                      
                      _repositories.Add(type, repositoryInstance);
                  }
      
                  return (IRepository<T>) _repositories[type];
              }
      
      
      

      Also, could you please confirm that in the class that is calling your new extension method that it indeed has a using statement with the fully qualified namespace for both the standard generic repository and the fully qualified namespace for newly added extension method? In the download sample app, these happen to be in the same namespace.

  91. I’m a bit confused about something. In your repository you reference the IDbSet interface which requires you to reference Entity Framework. I thought the goal of this was to remove your dependence from Entity Framework within your repository. Am I missing something?

    • Hi Bruce,

      The goal was to remove the dependencies from EF from anything above the repository layer, which in our case could be apps or (web) services. If you were ever to change out your ORM e.g. EF, you would only have to deal with changes in the Repository layer (project).

  92. Pingback: Modern Web Application Layered High Level Architecture with SPA, MVC, Web API, EF | Long Le's Blog

  93. Pingback: Using LinqPad to Query & Troubleshoot Custom Entity Framework DbContext, Unit of Work & Repository Pattern | Long Le's Blog

  94. How did you get this to work with LinqPad? When executing a query, I’m getting the following error:

    Unable to cast object of type ‘LINQPad.LINQPadDbConnection’ to type ‘System.Data.SqlClient.SqlConnection’.

    • The IUnitOfWork.Repository() will return the TEntity along with everything that it is associated with (complex member types), just make sure you don’t forget to eager load them. If there is a join you need to do that is beyond this, then you can simply write an extension method for static GetCustomerCustomQuery(IRepository this, param1, param2), extending the IResository is covered here in the post #Extensibility.

  95. Hi,

    i’ve implemented your Repo/UoW pattern but I’m facing problems when trying to eager load some entities.

    This simply doesn’t seem to be working unless the entities are already loaded by the UoW (in a different call).

    Have you experienced any of these problems?

    thanks for your help

    • Just to inform.

      I’ve also tried eager loading against the DbContext without using the Includes from RepositoryQuery and then everything is working smoothly.

      Could you check at your end if your code is performing ok?

    • Kristof, good catch! I forgot to append the include, I’ve updated the download link in the post with the fix.

      Before:

      
                  if (includeProperties != null)
                      includeProperties.ForEach(i => query.Include(i));
      
      

      After:

      
                  if (includeProperties != null)
                      includeProperties.ForEach(i =>{ query = query.Include(i); });
      
      

      Last but not least I’ve disabled lazy loading for best practices, this is to help people from accidentally loading large entity graphs.

      Data.NorthwindContext

      
              public NorthwindContext()
                  : base("Name=NorthwindContext")
              {
                  Configuration.LazyLoadingEnabled = false;
              }
      
      
      
  96. Very good article but the Query method should return an interface IRepositoryQuery instead of a concrete object to be independent with Entity Framework.

  97. Pingback: Implementing DI & IoC Pattern in MVC 4 with MEF 2 Attributeless using Conventions with RegistrationBuilder in .NET 4.5 – Part 2 | Long Le's Blog

  98. Pingback: MVC 4 with DI & IoC with MEF 2 Attribute-less using Conventions with RegistrationBuilder in .NET 4.5 – Part 2 | Long Le's Blog

  99. Pingback: Generically Implementing the Unit of Work & Repository Pattern with Entity Framework in MVC & Simplifying Entity Graphs – Part 2 (MVC 4 & DI, IoC with MEF 2 Attributeless Conventions .NET 4.5) | Long Le's Blog

  100. Pingback: Generically Implementing the Unit of Work & Repository Pattern with Entity Framework in MVC & Simplifying Entity Graphs – Part 2 (MVC 4 & DI, IoC with MEF Attributeless Conventions) | Long Le's Blog

Please Leave a Reply or Tweet me @LeLong37...!

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