title: Entity Framework as DAL how to implement Update and Delete correctly
body: <p>I'm writing a DAL class using EF4.0, I've read </p>
  
  <p><a href="http://www.codeproject.com/Articles/43367/ADO-NET-Entity-Framework-as-Data-Access-Layer" rel="nofollow">http://www.codeproject.com/Articles/43367/ADO-NET-Entity-Framework-as-Data-Access-Layer</a> </p>
  
  <p>and </p>
  
  <p><a href="http://msdn.microsoft.com/en-us/magazine/cc700340.aspx" rel="nofollow">http://msdn.microsoft.com/en-us/magazine/cc700340.aspx</a></p>
  
  <p>But when I test their code, I meet some problem with the Update and Delete method. </p>
  
  <p>The DAL class all code is below:</p>
  
  <pre><code>public class FriendlinkDA : IDisposable
  {
      private EdiBlogEntities context;
  
      public FriendlinkDA()
      {
          context = new EdiBlogEntities();
      }
  
      public void Dispose()
      {
          context.Dispose();
      }
  
      public FriendLink GetFriendLink(Guid id)
      {
          return context.FriendLink.FirstOrDefault(f =&gt; f.Id == id);
      }
  
      public void Update(FriendLink model)
      {
          // Way 1:  (throw exception)
          //context.Attach(model);
          //model.SetAllModified(context);
          //context.SaveChanges();
  
          // Way 2: 
          EntityKey key;
          object originalItem;
          key = context.CreateEntityKey("FriendLink", model);
          if (context.TryGetObjectByKey(key, out originalItem))
          {
              context.ApplyCurrentValues(key.EntitySetName, model);
              //context.ApplyPropertyChanges(key.EntitySetName, model);
          }
          context.SaveChanges();
      }
  
      public void Delete(FriendLink model)
      {
          // Way 1:
          context.Attach(model);
          context.DeleteObject(model);
          context.SaveChanges();
  
          // Way 2:
          //var item = context.FriendLink.FirstOrDefault(f =&gt; f.Id == model.Id);
          //context.DeleteObject(item);
          //context.SaveChanges();
      }
  }
  </code></pre>
  
  <p>The extension method is:</p>
  
  <pre><code>public static void SetAllModified&lt;T&gt;(this T entity, ObjectContext context) where T : IEntityWithKey
  {
      var stateEntry = context.ObjectStateManager.GetObjectStateEntry(entity.EntityKey);
      var propertyNameList = stateEntry.CurrentValues.DataRecordInfo.FieldMetadata.Select
        (pn =&gt; pn.FieldType.Name);
      foreach (var propName in propertyNameList)
          stateEntry.SetModifiedProperty(propName);
  }
  </code></pre>
  
  <p>In the application, I am use the DAL like this:</p>
  
  <pre><code>// Delete
  using (var optFriendlink = new FriendlinkDA())
  {
      var test = optFriendlink.GetFriendLink(new Guid("81F58198-D396-41DE-A240-FC306C7343E8"));
      optFriendlink.Delete(test);
  }
  
  // Update
  using (var optFriendlink = new FriendlinkDA())
  {
      var testLink = optFriendlink.GetFriendLink(new Guid("62FD0ACF-40C3-4BAD-B438-38BB540A6080"));
      testLink.Title = "ABC";
      optFriendlink.Update(testLink);
  }
  </code></pre>
  
  <p>Question 1:</p>
  
  <p>In Delete(), both way 1 and way 2 can work. Which one is better?</p>
  
  <p>Question 2:</p>
  
  <p>In Update(), way 1 give me an exception: <strong>The object cannot be attached because it is already in the object context. An object can only be reattached when it is in an unchanged state.</strong> </p>
  
  <p>on this statment: <strong>context.Attach(model);</strong></p>
  
  <p>but way 2 is fine.</p>
  
  <p>why is this happening? I also attach the model in Delete(), why Delete() is working fine? how I can write the update correctly?</p>