title: Entity Framework and WPF best practices
body: <p>Is it ever a good idea to work directly with the context? For example, say I have a database of customers and a user can search them by name, display a list, choose one, then edit that customer's properties.</p>
  
  <p>It seems I should use the context to get a list of customers (mapped to POCOs or <code>CustomerViewModels</code>) and then immediately close the context. Then, when the user selects one of the <code>CustomerViewModels</code> in the list the customer properties section of the UI populates.</p>
  
  <p>Next they can change the name, type, website address, company size, etc. Upon hitting a save button, I then open a new context, use the ID from the <code>CustomerViewModel</code> to retrieve that customer record, and update each of its properties. Finally, I call <code>SaveChanges()</code> and close the context. This is a LOT OF WORK.</p>
  
  <p>My question is why not just work directly with the context leaving it open throughout? I have read using the same context with a long lifetime scope is very bad and will inevitably cause problems. My assumption is if the application will only be used by ONE person I can leave the context open and do everything. However, if there will be many users, I want to maintain a concise unit of work and thus open and close the context on a per request basis. </p>
  
  <p>Any suggestions? Thanks.</p>
  
  <hr>
  
  <p>@PGallagher - Thanks for the thorough answer.<br>
  @Brice - your input is helpful as well</p>
  
  <p>However, @Manos D. the 'epitome of redundant code' comment concerns me a bit. Let me go through an example. Lets say I'm storing customers in a database and one of my customer properties is CommunicationMethod.</p>
  
  <pre><code>[Flags]
  public enum CommunicationMethod
  {
      None = 0,
      Print = 1,
      Email = 2,
      Fax = 4
  }
  </code></pre>
  
  <p>The UI for my manage customers page in WPF will contain three check boxes under the customer communication method (Print, Email, Fax). I can't bind each checkbox to that enum, it doesn't make sense. Also, what if the user clicked that customer, gets up and goes to lunch... the context sits there for hours which is bad. Instead, this is my thought process.</p>
  
  <p>End user chooses a customer from the list. I new up a context, find that customer and return a CustomerViewModel, then the context is closed (I've left repositories out for simplicity here).</p>
  
  <pre><code>using(MyContext ctx = new MyContext())
  {
      CurrentCustomerVM = new CustomerViewModel(ctx.Customers.Find(customerId));
  }
  </code></pre>
  
  <p>Now the user can check/uncheck the Print, Email, Fax buttons as they are bound to three bool properties in the CustomerViewModel, which also has a Save() method. Here goes.</p>
  
  <pre><code>public class CustomerViewModel : ViewModelBase
  {
      Customer _customer;
  
      public CustomerViewModel(Customer customer)
      {
          _customer = customer;
      }
  
  
      public bool CommunicateViaEmail
      {
          get { return _customer.CommunicationMethod.HasFlag(CommunicationMethod.Email); }
          set
          {
              if (value == _customer.CommunicationMethod.HasFlag(CommunicationMethod.Email)) return;
  
              if (value)
                  _customer.CommunicationMethod |= CommunicationMethod.Email;
              else
                  _customer.CommunicationMethod &amp;= ~CommunicationMethod.Email;
          }
      }
      public bool CommunicateViaFax
      {
          get { return _customer.CommunicationMethod.HasFlag(CommunicationMethod.Fax); }
          set
          {
              if (value == _customer.CommunicationMethod.HasFlag(CommunicationMethod.Fax)) return;
  
              if (value)
                  _customer.CommunicationMethod |= CommunicationMethod.Fax;
              else
                  _customer.CommunicationMethod &amp;= ~CommunicationMethod.Fax;
          }
      }
      public bool CommunicateViaPrint
      {
          get { return _customer.CommunicateViaPrint.HasFlag(CommunicationMethod.Print); }
          set
          {
              if (value == _customer.CommunicateViaPrint.HasFlag(CommunicationMethod.Print)) return;
  
              if (value)
                  _customer.CommunicateViaPrint |= CommunicationMethod.Print;
              else
                  _customer.CommunicateViaPrint &amp;= ~CommunicationMethod.Print;
          }
      }
  
      public void Save()
      {
          using (MyContext ctx = new MyContext())
          {
              var toUpdate = ctx.Customers.Find(_customer.Id);
              toUpdate.CommunicateViaEmail = _customer.CommunicateViaEmail;
              toUpdate.CommunicateViaFax = _customer.CommunicateViaFax;
              toUpdate.CommunicateViaPrint = _customer.CommunicateViaPrint;
  
              ctx.SaveChanges();
          }
      }
  }
  </code></pre>
  
  <p>Do you see anything wrong with this? </p>