pr0g33k

Getting Started: MVC 4, Entity Framework 5 Code First, and Unity

After several hours of banging my head against the wall, I finally have a good, working prototype for using Entity Framework 5 Code First in a MVC application with the Unity Inversion of Control (IoC) container for dependency injection. (Say that 3 times fast!) I'm using an IoC container for a couple of reasons. For one, it'll allow me to (somewhat) easily swap out components if I want. For example, if I want to use nHibernate for data access instead of Entity Framework, all I'll need to do is change to what the context, IRepository, and IUnitOfWork interfaces resolve. All of the code I write in the Controllers or elsewhere can stay the same. Another reason I want to use an IoC is because it'll make my components (somewhat) easy to mock (or fake) to supply a way to perform integration tests without having to use the actual services (e.g. I can create an object graph in code and use that in place of making calls to the database). Also, I'll be using the IoC to perform dependency injection (DI) so I'll "inject" my services into the controllers' contructors as well as the contructors of any other objects that depend on my services. This provides an easy way to create services and use them without having to write the code to instantiate them.

Let's Begin

First, let's create a MVC Web application. I'm creating a very simple application for an imaginary Parks & Recreation center so I'll call it "Recreation."

MVC project creation

For the type of MVC Web application, I'm going to go with the Basic template. I'm also going to create a unit test project but I'll save the unit tests for another post.

Basic MVC application

Once the project is created, add a new controller and name it "HomeController."

Home Controller

When the HomeController.cs file opens, right-click in the Index() method and select "Add View..."

Now run the application (F5) to make sure everything compiles and runs.

Create a Model/Data Access Layer

Next, we're going to add a separate class library for our entities/models. Add a new project to the solution and name it "Data."

Data class library

Once the project is created, add the assembly references for "System.ComponentModel.DataAnnotations." Then use the NuGet Package Manager to add Entity Framework.

Entity Framework

Next create folders named "Context" and "Models" and add the following classes:

Data Project set-up

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace Data.Models
{
    public class Facility
    {
        [Key]
        public Int32 Id { get; set; }

        [StringLength(100)]
        public String Name { get; set; }
        public Int32 SquareFeet { get; set; }

        [Timestamp]
        public Byte[] ConcurrencyToken { get; set; }

        public virtual ICollection<Reservation> Reservations { get; set; }
    }
}
    
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace Data.Models
{
    public class Guest
    {
        [Key]
        public Int32 Id { get; set; }

        [StringLength(100)]
        public String FirstName { get; set; }
        [StringLength(100)]
        public String LastName { get; set; }

        [Timestamp]
        public Byte[] ConcurrencyToken { get; set; }

        public virtual ICollection<Reservation> Reservations { get; set; }
    }
}
    
using System;
using System.ComponentModel.DataAnnotations;

namespace Data.Models
{
    public class Reservation
    {
        [Key]
        public Int32 Id { get; set; }
        public DateTime StartDateTime { get; set; }
        public DateTime EndDateTime { get; set; }

        [Display(Name = "Facility")]
        public Int32 FacilityId { get; set; }

        [Display(Name = "Guest")]
        public Int32 GuestId { get; set; }

        [Timestamp]
        public Byte[] ConcurrencyToken { get; set; }

        public virtual Facility Facility { get; set; }
        public virtual Guest Guest { get; set; }
    }
}
    
using Data.Models;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;

namespace Data.Context
{
    public class RecreationContext : DbContext
    {
        public RecreationContext()
            : base("name=DefaultConnection")
        {
        }

        public DbSet<Facility> Facilities { get; set; }
        public DbSet<Guest> Guests { get; set; }
        public DbSet<Reservation> Reservations { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
            modelBuilder.Entity<Facility>().Property(p => p.ConcurrencyToken).IsConcurrencyToken();
            modelBuilder.Entity<Guest>().Property(p => p.ConcurrencyToken).IsConcurrencyToken();
            modelBuilder.Entity<Reservation>().Property(p => p.ConcurrencyToken).IsConcurrencyToken();
        }
    }
}
    

The "RecreationContext" class is like our gateway to the database. We're first going to use it to create the database. The three DbSet properties establish our tables available through the context. The "OnModelCreating" method allows us to set additional characteristics or properties on the tables as well as do things like change the way columns are named or create specific types of relationships between our tables. Here, we're setting up the "ConcurrencyToken" properties in our models to render as timestamp columns in the database. I'm doing this so that we can handle optimistic concurrency (when two or more people retrieve the same record and then attempt to save and overwrite one of the other person's changes).

To enable Entity Framework Code First, open the Package Manager Console, set the default project to the "Data" project, and type the following:

Package Manager Console - Enable Migrations

This will add a new directory to your project, "Migrations," and a new class, "Configuration." The configuration class has a method that will help us seed the new database with some initial values. Replace the Seed method with this:

protected override void Seed(Data.Context.RecreationContext context)
{
    var facilities = new List<Facility>()
    {
        new Facility(){
            Name = "West Pavillion",
            SquareFeet = 12020,
            Reservations = new List<Reservation>()
        },
        new Facility(){
            Name = "East Pavillion",
            SquareFeet = 14500,
            Reservations = new List<Reservation>()
        },
        new Facility(){
            Name = "Bounce House",
            SquareFeet = 3000,
            Reservations = new List<Reservation>()
        },
        new Facility(){
            Name = "Botanical Garden",
            SquareFeet = 23123,
            Reservations = new List<Reservation>()
        }
    };

    facilities.ForEach(e => context.Facilities.AddOrUpdate(i => i.Name, e));
    context.SaveChanges();

    var guests = new List<Guest>()
    {
        new Guest(){
            FirstName = "Adam",
            LastName = "Jones",
            Reservations = new List<Reservation>()
        },
        new Guest(){
            FirstName = "Tiffany",
            LastName = "Bresnev",
            Reservations = new List<Reservation>()
        },
        new Guest(){
            FirstName = "Jackson",
            LastName = "Ackton",
            Reservations = new List<Reservation>()
        }
    };

    guests.ForEach(e => context.Guests.AddOrUpdate(i => i.LastName, e));
    context.SaveChanges();

    var reservations = new List<Reservation>()
    {
        new Reservation(){
            StartDateTime = new DateTime(2013, 1, 1),
            EndDateTime = new DateTime(2013, 1, 1),
            FacilityId = facilities.Single(p => p.Name == "West Pavillion").Id,
            GuestId = guests.Single(p => p.LastName == "Jones").Id
        },
        new Reservation(){
            StartDateTime = new DateTime(2013, 2, 1),
            EndDateTime = new DateTime(2013, 2, 1),
            FacilityId = facilities.Single(p => p.Name == "Bounce House").Id,
            GuestId = guests.Single(p => p.LastName == "Bresnev").Id
        },new Reservation(){
            StartDateTime = new DateTime(2013, 3, 1),
            EndDateTime = new DateTime(2013, 3, 1),
            FacilityId = facilities.Single(p => p.Name == "Botanical Garden").Id,
            GuestId = guests.Single(p => p.LastName == "Ackton").Id
        }
    };

    reservations.ForEach(e => context.Reservations.AddOrUpdate(i => new { i.StartDateTime, i.EndDateTime, i.FacilityId, i.GuestId }, e));
    context.SaveChanges();
}
    

When we tell Entity Framework to create the database, the Package Manager Console will look at our start-up project (the MVC project, in this case) and look for the connection string we specified in the RecreationContext class ("DefaultConnection"). I'm going to leave the connection string as the default and create a local database file in the App_Data folder. If you want the database to be created elsewhere, just update the connection string in the Web.config. Next, open the Package Manager Console and type the following:

Package Manager Console - Initial Create

This will create a class named "InitialCreate" that has the code necessary for Entity Framework to create the tables in our database. To create the database and generate the tables, type the following in the Package Manager Console:

Package Manager Console - update-database

If you open the Server Explorer -> DefaultConnection -> Tables, right-click on the Guest table, and select "Show Table Data," you should see the following:

Server Explorer

Let's make sure it works from our MVC application. Replace your HomeController with this:

using Data.Context;
using System.Linq;
using System.Web.Mvc;

namespace Recreation.Controllers
{
    public class HomeController : Controller
    {
        private RecreationContext db = new RecreationContext();

        public ActionResult Index()
        {
            return View(db.Guests.ToList());
        }

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

Then modify your Views -> Home -> Index.cshtml file to look like this:

@model List<Data.Models.Guest>
@{
    ViewBag.Title = "Home";
}

<h2>@ViewBag.Title</h2>
<ul>
    @foreach (var m in Model)
    {
        <li>@m.FirstName @m.LastName</li>
    }
</ul>
    

Run the application (F5) and you should see the three names we seeded to the database when it was created.

Using the Unity IoC Container to Inject Dependencies in Your Controller

First, install the Unity bootstrapper for ASP.NET MVC.

NuGet Unity Bootstrapper

This will also add the Unity NuGet package. The bootstrapper adds the necessary files in the MVC project's App_Start directory to initialize Unity and set the dependencies (the things you want to inject into other classes or methods). If you look in App_Start, you'll see two new files: UnityConfig.cs and UnityMvcActivator.cs. UnityMvcActivator uses WebActivatorEx to call the class's Start() method during application start. Of particular interest in the Start() method are the following lines:

// TODO: Uncomment if you want to use PerRequestLifetimeManager
// Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
    

Unity has what's called "lifetime managers" that manages how long any given object stays instantiated (alive). The The PerRequestLifetimeManager calls Dispose() on any object that makes use of the manager at the end of the HTTP request. We want to do this for our ObjectContext (RecreationContext) object so that it doesn't stay alive on the server, available for other requests. Make sure you uncomment the line so that we can safely dispose of any resources that implement IDisposable.

The reason for my aforementiond head-banging was that I installed "Unity" and "Unity.MVC4" NuGet packages instead of the "Unity bootstrapper for ASP.NET MVC" package. The PerRequestLifetimeManager and UnityPerRequestHttpModule are only available in the bootstrapper package. I attempted to build several per-request lifetime managers but could never get them to call Dispose() on my managed services. It was ultimately the HttpModule that I was missing.

Using the Inversion of Control, Repository, and Unit Of Work Patterns

The Inversion of Control (IoC) pattern is all about resolving one type to another type. This resolution could be based on inheritance but most often you'll see it based on an interface. With this pattern, you develop against an interface and let the IoC container resolve it to a concrete implementation of that interface. You could have any number of implementations, it's up to the IoC container to create one for you. One of the ways it can do this is through Dependency Injection (DI). What you have is a consumer component (e.g. a MVC controller) that declares a dependency (or multiple dependencies) that it needs to get its job done. (Most commonly, you'll see this done through the constructor but some IoC frameworks allow you to inject through properties.) The IoC container creates an instance of a class that implements that given interface at runtime and "injects" it into that component. This pattern is somewhat like the Factory method pattern except that IoC relies on an external framework to operate (e.g. Unity, Windsor, Ninject, StructureMap). So IoC is really more of an architectural pattern as opposed to a design pattern.

What we want now is an interface we can program against to get data from the Entity Framework ObjectContext (RecreationContext) we set up earlier. The interface should be generic enough that we can swap it out for another data access framework if we want but still robust enough to give us what we need to get things done in our controllers. The Repository pattern is ideal for this situation:

A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes.

So the repository is responsible for persisting our objects in memory but what about when it comes time to save changes to the collection(s) back to the database? That's where the Unit of Work pattern comes into play:

A Unit of Work keeps track of everything you do during a business transaction that can affect the database. When you're done, it figures out everything that needs to be done to alter the database as a result of your work.

Perfect!

So that we can reuse our Repository and UnitOfWork classes, lets create a separate class library and call it something like "Core." Note that I'm placing it in the Projects directory and not the Recreation directory. That way I can easily reference the assembly when creating other projects. A "core" assembly is a great place to store commonly used code like extension methods, helper methods, and anything else you may want to use from project-to-project. (Ideally, you would place the IRepository and IUnitOfWork interfaces - along with their dependencies - in a "core" assembly and then create another assembly with an ORM-specific implementation but I'm going to combine them at this time for the sake of simplicity.)

Core Class Library

After you create the class library, install Entity Framework from the NuGet Package Manager then add these interfaces, classes, and enum:

namespace Core
{
    public enum EntityStatus : int
    {
        Added,
        Deleted,
        Detached,
        Modified,
        Unchanged
    }
}
    
using System;
using System.Runtime.Serialization;

namespace Core
{
    public class ConcurrencyException : SystemException
    {
        public ConcurrencyException()
            : base()
        {
        }

        public ConcurrencyException(String message)
            : base(message)
        {
        }

        public ConcurrencyException(String message, Exception innerException)
            : base(message, innerException)
        {
        }

        public ConcurrencyException(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
        }
    }
}
    
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace Core
{
    public interface IRepository<T> : IDisposable where T : class
    {
        IQueryable<T> GetQueryable();
        IEnumerable<T> GetAll();
        IEnumerable<T> Find(Expression<Func<T, Boolean>> where);
        T Single(Expression<Func<T, Boolean>> where);
        T First(Expression<Func<T, Boolean>> where);
        void Delete(T entity);
        void Add(T entity);
        void Attach(T entity);
        void Attach(T entity, EntityStatus status);
    }
}
    
using System;

namespace Core
{
    public interface IUnitOfWork : IDisposable
    {
        void SaveChanges();
    }
}
    
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity.Infrastructure;
using System.Data.Objects;
using System.Linq;
using System.Linq.Expressions;

namespace Core
{
    public class Repository<T> : IRepository<T> where T : class
    {
        private readonly IObjectContextAdapter _ObjectContextAdapter;
        IObjectSet<T> _ObjectSet;

        public Repository(IObjectContextAdapter objectContextAdapter)
        {
            _ObjectContextAdapter = objectContextAdapter;
            _ObjectSet = objectContextAdapter.ObjectContext.CreateObjectSet<T>();
        }

        public IQueryable<T> GetQueryable()
        {
            return _ObjectSet;
        }

        public IEnumerable<T> GetAll()
        {
            return _ObjectSet.ToList();
        }

        public IEnumerable<T> Find(Expression<Func<T, Boolean>> where)
        {
            return _ObjectSet.Where(where);
        }

        public T Single(Expression<Func<T, Boolean>> where)
        {
            return _ObjectSet.Single(where);
        }

        public T First(Expression<Func<T, Boolean>> where)
        {
            return _ObjectSet.First(where);
        }

        public void Delete(T entity)
        {
            _ObjectSet.DeleteObject(entity);
        }

        public void Add(T entity)
        {
            _ObjectSet.AddObject(entity);
        }

        public void Attach(T entity)
        {
            Attach(entity, EntityStatus.Unchanged);
        }

        public void Attach(T entity, EntityStatus status)
        {
            _ObjectSet.Attach(entity);
            _ObjectContextAdapter.ObjectContext.ObjectStateManager.ChangeObjectState(entity, GetEntityState(status));
        }

        public void Dispose()
        {
            if (_ObjectContextAdapter != null)
                _ObjectContextAdapter.ObjectContext.Dispose();

            GC.SuppressFinalize(this);
        }

        private EntityState GetEntityState(EntityStatus status)
        {
            switch (status)
            {
                case EntityStatus.Added:
                    return EntityState.Added;
                case EntityStatus.Deleted:
                    return EntityState.Deleted;
                case EntityStatus.Detached:
                    return EntityState.Detached;
                case EntityStatus.Modified:
                    return EntityState.Modified;
                default:
                    return EntityState.Unchanged;
            }
        }
    }
}
    
using System;
using System.Data;
using System.Data.Entity.Infrastructure;

namespace Core
{
    public class UnitOfWork : IUnitOfWork
    {
        private readonly IObjectContextAdapter _ObjectContextAdapter;

        public UnitOfWork(IObjectContextAdapter objectContextAdapter)
        {
            _ObjectContextAdapter = objectContextAdapter;
        }

        public void SaveChanges()
        {
            try
            {
                _ObjectContextAdapter.ObjectContext.SaveChanges();
            }
            catch (OptimisticConcurrencyException oce)
            {
                throw new ConcurrencyException(oce.Message, oce.InnerException);
            }
            catch (DataException)
            {
                throw;
            }
        }

        public void Dispose()
        {
            if (_ObjectContextAdapter != null)
                _ObjectContextAdapter.ObjectContext.Dispose();

            GC.SuppressFinalize(this);
        }
    }
}
    

To implement the repository and unit of work into our MVC application, update the UnityConfig.cs file as follows:

using Core;
using Data.Context;
using Microsoft.Practices.Unity;
using System;
using System.Data.Entity.Infrastructure;

namespace Recreation.App_Start
{
    /// <summary>
    /// Specifies the Unity configuration for the main container.
    /// </summary>
    public class UnityConfig
    {
        #region Unity Container
        private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
        {
            var container = new UnityContainer();
            RegisterTypes(container);
            return container;
        });

        /// <summary>
        /// Gets the configured Unity container.
        /// </summary>
        public static IUnityContainer GetConfiguredContainer()
        {
            return container.Value;
        }
        #endregion

        /// <summary>Registers the type mappings with the Unity container.</summary>
        /// <param name="container">The unity container to configure.</param>
        /// <remarks>There is no need to register concrete types such as controllers or API controllers (unless you want to 
        /// change the defaults), as Unity allows resolving a concrete type even if it was not previously registered.</remarks>
        public static void RegisterTypes(IUnityContainer container)
        {
            // NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
            // container.LoadConfiguration();

            // TODO: Register your types here
            container.RegisterType<IObjectContextAdapter, RecreationContext>(new PerRequestLifetimeManager());
            container.RegisterType(typeof(IRepository<>), typeof(Repository<>));
            container.RegisterType<IUnitOfWork, UnitOfWork>();
        }
    }
}
    

What we're doing here is registering the interfaces and associating them with a concrete type in the RegisterTypes() method. Throughout the MVC application, we'll program against the interface but at runtime, Unity will inject a concrete instance of the interface.

In the above code, the RecreationContext is instantiated per-request thanks to the PerRequestLifetimeManager. Here's the cool part: both Repository and UnitOfWork have constructors that accept IObjectContextAdapter. When the concrete implementations are instantiated, Unity injects the RecreationContext into them and then they get injected into the controller (see below). Both the Repository and the UnitOfWork then share the same context per request so that anything that happens in the Repository gets reflected in the UnitOfWork. How freaking cool is that?!

Now we can update our HomeController to look like this:

using Core;
using Data.Models;
using System.Web.Mvc;

namespace Recreation.Controllers
{
    public class HomeController : Controller
    {
        IRepository<Guest> _GuestRepository;

        public HomeController(IRepository<Guest> guestRepository)
        {
            _GuestRepository = guestRepository;
        }

        public ActionResult Index()
        {
            return View(_GuestRepository.GetAll());
        }

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

Now run the application (F5) and verify that the save values from the database are displayed in the view.

When the controller is created, Unity inspects its constructor and compares the types in the signature with the registered types in its container. In this case, it found a generic IRepository<> interface and passed in an instance of the Repository<> class. By making the IRepository interface and Repository concrete implementation generic, we can create repositories for any number of Entity objects. You can inject as many items into a constructor as you want, too. Just add them to the constructor's method signature [e.g. public HomeController(IRepository<Guest> guestRepository, IRepository<Facility> facilityRepository, IRepository<Reservation> reservationRepository) and so on...]

When you make changes through the repository, you're actually making changes to the Entities in the underlying ObjectContext. When it comes time to commit those changes back to the database, the Unit of Work we created earlier has that responsibility. Update your HomeController to this:

using Core;
using Data.Models;
using System;
using System.Web.Mvc;

namespace Recreation.Controllers
{
    public class HomeController : Controller
    {
        IRepository<Guest> _GuestRepository;
        IUnitOfWork _UnitOfWork;

        public HomeController(IRepository<Guest> guestRepository, IUnitOfWork unitOfWork)
        {
            _GuestRepository = guestRepository;
            _UnitOfWork = unitOfWork;
        }

        public ActionResult Index()
        {
            return View(_GuestRepository.GetAll());
        }

        public ActionResult Edit()
        {
            return View(_GuestRepository.First(g => g.LastName == "Bresnev"));
        }

        [HttpPost]
        public ActionResult Edit(Guest guest)
        {
            _GuestRepository.Attach(guest, EntityStatus.Modified);

            if (ModelState.IsValid)
            {
                try
                {
                    _UnitOfWork.SaveChanges();
                }
                catch (ConcurrencyException)
                {
                    ModelState.AddModelError(String.Empty, "The record you attempted to edit was modified by another user after you got the original value. Your edit operation was canceled. If you still want to edit this record, save it again.");
                }
                catch (Exception)
                {
                    ModelState.AddModelError(String.Empty, "Unable to save changes. Please try again.");
                }
            }

            return View(guest);
        }

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

Right-click within the Edit() method and add a View. Change the Edit.cshtml view to look like this:

@model Data.Models.Guest
@{
    ViewBag.Title = "Edit";
}

<h2>@ViewBag.Title</h2>
<ul>
    <li>@Model.FirstName @Model.LastName</li>
</ul>
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    @Html.TextBoxFor(m => m.FirstName);
    
    @Html.HiddenFor(m => m.Id)
    @Html.HiddenFor(m => m.LastName)
    @Html.HiddenFor(m => m.ConcurrencyToken)
    <input type="submit" value="Change First Name" />
}
    

I realize this is a pretty lame example but I just wanted to get the idea across.

The reason for creating my own ConcurrencyException and managing my own Entity state/status is that I didn't want to create any dependencies on Entity Framework in the interfaces. I'm not sure about other ORM's but I can imagine that there are ways on others to manage concurrency exceptions or the status change of an object. The point, though, is to make an interface that's as neutral as possible to a concrete implementation so that you can change the concrete implementation without having to change the interface and the code depending on that interface.

Please let me know if you have any suggestions on how to make this better!

You can get the code here.

Comments:

  1. Nanette

    Great Tutorial! Simple and easy to follow.
  2. pr0g33k

    Thanks for visiting! I'm glad you enjoyed it. I'll have several more posts related to this one soon so please bookmark me.
  3. Aziz

    Nice! very easy to follow.
  4. mr.dean

    Well done, very easy to understand. Hope to read more on this....Thanks.
  5. Muhammad Usman

    Well done, very easy and simply understand this blog.... Thanks....
  6. Dan Henning

    Over the past 5 days, I've read dozens of tutorials, (IoC, DI, Repository, Unit of Work, etc.), and this one is the most concrete and specific example, for sure. Thanks!
  7. pr0g33k

    Thanks! I just posted an update to the Repository and UnitOfWork code that you might want to check out (see "Next Steps: Adding a Service Layer and Validation"). By encapsulating your Repository and UnitOfWork in a Service Layer, you can centralize a lot of repetitive business and validation logic. Thanks again for visiting!
  8. noob

    Tried to add "new project" to solution and there is no option to allow me to do that nor is there an option to allow me to creat a folder. Any tips?
  9. pr0g33k

    It is probably an issue with the NuGet packages in the original solution. If you are trying to open the projects from this tutorial in a new, empty solution, you may run into an issue where the new solution cannot find the file paths of the NuGet packages referenced in the projects. I suggest that you extract the .zip file attached to this tutorial and open the Recreation.sln solution file in the Recreation directory. The package restore feature should restore the NuGet packages for each project in the solution. 
    
    Another possible explanation for your situation is that you've opened the solution file from the .zip file without first extracting it. If you received a message that not all of the projects could be loaded and you're unable to perform any of the normal operations on the solution, this may be the reason. Make sure you've extracted all of the files before you open the solution or any of the projects.
    
    If I've missed the mark, please let me know and I'll try and help further.
  10. Cheachwood

    Hi,
    
    Great tutorial, also I had an error when enabling migrations on the Data project, here is the error Unhandled Exception: System.IO.FileLoadException: Could not load file or assembly 'EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040).
    So it was du to the fact that the Reservation MVC project was defined as the started project on my solution, and it was referencing Tentity 5.0, so I search on the web and I had a partial answer on this page http://msdn.microsoft.com/en-us/data/jj618307.aspx, also this didn't gave me the total response, I also need to upgrade Entity 5.0 to Entity 6.1 on the Reservation project and all rocks!!!
    Hope that will help someone else or helped you to update your tutorial.
    Thanx
    
  11. pr0g33k

    Thanks! I'm glad you got the issue resolved and thanks for sharing the solution. 
    
    You mentioned that the issue might have been due to the MVC project being set as the startup project. I should have pointed this out more specifically in the tutorial but you can change the default project in the Package Manager Console when you run the Entity Framework commands. There's a dropdown for the current projects called "Default project" in the console. Take a look at the screenshots of the Package Manager Console in the tutorial and you'll notice the "Default project" is set to the "Data" project. When you run the Entity Framework commands, you'll want to change the dropdown selection to your project that contains the DbContext-derived class. Entity Framework will still reference the connection string in your startup project to make the connection to your database.
  12. Chandra Prakash

    Thank you Thank you Thank you 
  13. Bilal

    Thanks for the nice article. I have two questions:
    1- How about unit testing? Shall I provide a fake "Repository<>" implementation? Is that enough?
    2- If we want to use something different from EF, how to go about that?
    
    Regards
    Bilal
    
  14. pr0g33k

    I'm not much of a unit tester but I was able to use the Moq testing framework to create Moq'd IRepository<> objects for testing. It was really easy. You could also create a fake Repository<> but take a look at Moq and see if you like it. I think it might be easier than creating a fake Repository<>.
    
    I found it very useful to create a separate class library for the Entity Framework implementation of IRepository and IUnitOfWork. Take a look at my follow-up article http://www.pr0g33k.com/Blog/2006/Next-Steps-Adding-a-Service-Layer-and-Validation and you'll see how I structured the projects. You should be able to create your own implementation of IRepository and IUnitOfWork using your ORM - just implement the interfaces in your own classes and fill out the methods with code specific to your ORM. I tried to make everything generic with this strategy in mind but I'd be very interested in hearing from you how well it worked for another ORM. The only thing I'm really uncertain about is how other ORM's handle concurrency issues.
  15. Bilal

    pr0g33k, Thanks a lot! I am a big fan of writing generic code, especially when it comes to dealing with DAL.
    
    I might want to try old ADO.NET as one provider to prove the point! Also, NHibernate could be a possible implementation.
    
    Regards
    Bilal
    
  16. Jasmin

    Thanks a lot for this material and got excellent idea on repository and unit of work pattern along with DI. Its awesome material i was banging my my head for long time and finally my thirst over here. Thanks again
    
    Regards,
    Jasmin
  17. pr0g33k

    Jasmin,
    
    I'm so glad I was able to help! I was pretty frustrated at first as well. Since you found the Repository and UnitOfWork useful, you might be interested in my follow-up article (http://www.pr0g33k.com/Blog/2006/Next-Steps-Adding-a-Service-Layer-and-Validation) where I talk about the Service Layer pattern.
    
    Happy coding!
  18. anion

    hey man, this is very nice!! thank you
  19. RK

    Hi pr0g33k,
    
    great job, very easy to implement and use
    
    may I ask a question?
    I have a many to many relationship.
    Creating a record in one table works fine: the many-to-many table records are created.
    
    But updating one table's record has no effect on the many-to-many table records.
    
    Any idea how to get the update to work?
    
    
    Thank you
  20. pr0g33k

    Is it an EF-created many-to-many table or did you create your own model with additional properties for the many-to-many? I'll be happy to take a look at it for you. Is there any way you can send me a simplified version of what you're trying to do?
  21. RK

    Hi pr0g33k,
    
    Thank you for your quick reply.
    It is an EF-created many-to-many table, with no additional properties.
    
    Finally, I got it to work, I just refreshed the entity by refetching its properties from the repository 
    (Repository.First(...)), and then I set EntityStatus to Modified before saving changes (_UnitOfWork.SaveChanges()).
    
    Refreshing the entity solved my update issue.
    
    I am new to repository-unitofwork-unity pattern and I am very glad I stumbled on your blog.
    I read other blogs, but failed to get things to work their way....
    
    Again, thank you for your great articles.
  22. pr0g33k

    You're very welcome. I'm glad that you got it to work. Dealing with relationships can be tricky (and I'm not just talking about EF. LOL!). One thing to consider is that the data delivered from the database is a single result set so any joins in your query (don't forget lazy loading of related entities) multiplies the amount of data across the wire. If your entities are heavy with many properties and you're requesting a lot of them, it can be a pretty serious drag on the performance of your application. You might consider firing up SQL Server Profiler and take a look at the results of the queries if you're ever concerned about how much data is being transferred from the database. In some instances, you could benefit from multiple queries and manually assembling your entity graph instead of a single query that contains all of your entities. It would be nice if EF took advantage of multiple result sets and the ADO.NET DataRelation to tie the result sets back together when populating entity graphs. It appears that someone might be working on this, though: https://entityframework.codeplex.com/workitem/1286
  23. Treasa

    Very nice article. It is very clear and precise.
  24. Muhammad Afzal

    Very nice and simple
    
    will same code work with EF 6 or 7 ???? if you've updated this code kindly let me know 
    
    thanks
  25. pr0g33k

    This code works with EF6 (I use it in a production environment today) but EF7 is untested with it at this point and, honestly, will likely not work with the code in this blog post. The ObjectContext API is going away in EF7 so the IObjectContextAdapter interface will not be around when EF7 is released (that's an assumption but one that I feel is safe to make). Dependency Injection is a pattern that Microsoft is placing front-and-center with ASP.NET vNext, though, so I suspect that much of what is in this blog post will be replaced by the new features of ASP.NET vNext and EF7. As soon as I get better acquainted with EF7, I'll try to do a follow-up to this post with what I discover related to DI and EF7.
  26. Csharper

    Hi, nice example. I was wondering though you have a reference to the data in your presentationlayer....it feels wrong because now your presentationlayer is dependent on it...which means a lot of work if you replace the db with another one that has different names.
    i think you need to make viewmodels that map to your db-models. you are using the db models directly from the the data..
  27. Vishnu

    Very nice and simple explanation.Please keep up similar posting.
    
    Thanks
Leave a comment
  1. CAPTCHA