title: How to filter DbContext in a multi-tenant application using Entity Framework with MVC4
body: <p>I am developing a <strong>multi-tenant web application</strong> using <strong>MVC4</strong> and <strong>EF5</strong>. I previously asked this question regarding filtering my DbContext: <a href="https://stackoverflow.com/questions/17151192">Is it bad practice to filter by ID within the repository pattern</a>.</p>
  
  <p>Apparently, my approach was sound, but it was suggested that rather than handling all filtering in that single repository, I provide a <strong>context already filtered to tenant level</strong> using <em>'a repository or DBContextWrapper class that would feed your [my] normal repository'</em>.</p>
  
  <p>Unfortunately I am no MVC expert, so I started implementing this as best I could, but upon researching filtering in EF for other multi-tenant applications I found a question for a <strong>very similar case</strong> <a href="https://stackoverflow.com/questions/15349819/">Multi-tenancy web application with filtered dbContext</a>, though completely failed to understand the answer to it.</p>
  
  <p>In my application, the CompanyID is a property of the User class, so should be taken directly from the authenticated user. Eg:</p>
  
  <pre><code>int CompanyID = db.Users.Single(u =&gt; u.Email == User.Identity.Name).CompanyID;
  </code></pre>
  
  <p>My current approach does appear to work, however I'm pretty sure I have gone about it the wrong way and/or have done it inefficiently based on what I've seen in other Questions about doing the same sort of thing. In another question <a href="https://stackoverflow.com/questions/11412626/">Solutions for a simple multi tenant web application with entity framework</a> reflection is used to do this, but I'm not able to work out whether it would apply in my case, or even how to use it.</p>
  
  <p>I would be extremely appreciative if anyone can explain the best way of going about this, and the pros/cons of differing ways. Thanks :)</p>
  
  <p>My current implementation is as follows:</p>
  
  <p><strong>DB</strong></p>
  
  <ul>
  <li>One database, multiple tenants.</li>
  <li>All tables link back to Company table one way or another, although not all have a CompanyID field.</li>
  </ul>
  
  <p><strong>TestController.cs</strong></p>
  
  <pre><code>public class TestController : Controller
  {
      private BookingSystemEntities db = new BookingSystemEntities();
      public ActionResult Index()
      {
          var user = db.Users.Single(u =&gt; u.Email == User.Identity.Name);
          IBookingSystemRepository rep = new BookingSystemRepository(db, user);            
          return View(rep.GetAppointments(false));
      }
  
  }
  </code></pre>
  
  <p><strong>BookingSystemRepository.cs</strong></p>
  
  <pre><code>public class BookingSystemRepository : IBookingSystemRepository
  {
      private CompanyBookingSystemRepository db;
  
      public BookingSystemRepository(BookingSystemEntities context, User user)
      {
          this.db = new CompanyBookingSystemRepository(context, user);
      }
  
      public IEnumerable&lt;Appointment&gt; GetAppointments()
      { return GetAppointments(false); }
  
      public IEnumerable&lt;Appointment&gt; GetAppointments(bool includeDeleted)
      {
          return includeDeleted
              ? db.Appointments
              : db.Appointments.Where(a =&gt; a.Deleted.HasValue);
      }
  
      public IEnumerable&lt;Client&gt; GetClients()
      { return GetClients(false); }
  
      public IEnumerable&lt;Client&gt; GetClients(bool includeDeleted)
      {
          return includeDeleted
              ? db.Clients
              : db.Clients.Where(c =&gt; c.Deleted.HasValue);
      }
  
      public void Save()
      {
          db.SaveChanges();
      }
  
      public void Dispose()
      {
          if (db != null)
              db.Dispose();
      }
  }
  </code></pre>
  
  <p><strong>CompanyBookingSystemRepository.cs</strong></p>
  
  <pre><code>public class CompanyBookingSystemRepository
  {
      private BookingSystemEntities db;
      private User User;
      public IEnumerable&lt;Appointment&gt; Appointments { get { return db.Appointments.Where(a =&gt; a.User.CompanyID == User.CompanyID).AsEnumerable&lt;Appointment&gt;(); } }
      public IEnumerable&lt;Client&gt; Clients { get { return db.Clients.Where(a =&gt; a.CompanyID == User.CompanyID).AsEnumerable&lt;Client&gt;(); } }
  
      public CompanyBookingSystemRepository(BookingSystemEntities context, User user)
      {
          db = context;
          this.User = user;
      }
  
      public void SaveChanges()
      {
          db.SaveChanges();
      }
  
      public void Dispose()
      {
          if (db != null)
              db.Dispose();
      }
  }
  </code></pre>