title: Simplified way to handle one-to-many relationship updates in Entity Framework?
body: <p>I'd been doing some research looking for a way to simplify the code to update a one-to-many relationship in Entity Framework, there are plenty of similar questions regarding how to update a one-to-many relationships but I couldn't find any simple solution.</p>
  
  <p>Assuming I have the following model classes:</p>
  
  <pre><code>public class Author
  {
      public int AuthorId { get; set; }
      ...
      public virtual ICollection&lt;Book&gt; Books { get; set; }
  }
  
  public class Book
  {
      public int BookId { get; set; }
      ...
      public int? AuthorId { get; set; }
      public virtual Author Author { get; set; }
  }
  
  
  protected override void OnModelCreating(DbModelBuilder modelBuilder)
      {
          modelBuilder.Entity&lt;Book&gt;()
             .HasOptional(b =&gt; b.Author)
             .WithMany(v =&gt; v.Books)
             .HasForeignKey(s =&gt; s.AuthorId)
             .WillCascadeOnDelete(true);
  
  ...
  </code></pre>
  
  <p>And considering a disconnected scenario where I want to:</p>
  
  <ul>
  <li>Add new Books to the collection</li>
  <li>Remove Books from the collection</li>
  <li>Modify exisitng Books of the collection</li>
  </ul>
  
  <p>My first approach was to clear the author's book collection and set again with a new one:</p>
  
  <pre><code>var author = authorRepository.GetAuthor(authorId);
  author.Books.Clear();
  author.Books = updatedBooksCollection;
  authorRepository.UpdateAuthor(author);
  </code></pre>
  
  <p>So, this approach works but it creates <strong>orphan records</strong> in the database.</p>
  
  <p>One way to solve this is with an <strong>Identifying Relationship</strong>:</p>
  
  <pre><code>public class Book
  {
      [Key, Column(Order = 1), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
      public int BookId { get; set; }
      ...
      [Key, Column(Order = 2), ForeignKey("Author")]
      public int AuthorId { get; set; }
      public virtual Author Author { get; set; }
  }
  </code></pre>
  
  <p>This works fine when I clear the collection and set a new one <strong>BUT I have to change my table schema adding a composite key</strong>.</p>
  
  <p>After researching a while I found this article (<a href="http://www.entityframeworktutorial.net/EntityFramework4.3/update-one-to-many-entity-using-dbcontext.aspx" rel="nofollow">http://www.entityframeworktutorial.net/EntityFramework4.3/update-one-to-many-entity-using-dbcontext.aspx</a>) which explains clearly how to manage one-to-many relationship updates in a disconnected scenario like this.</p>
  
  <p>I added this method to my repository class:</p>
  
  <pre><code>private void UpdateBooks(IEnumerable&lt;Book&gt; existingBooks, IEnumerable&lt;Book&gt; updatedBooks)
  {
      var addedBooks = updatedBooks.Except(existingBooks, x =&gt; x.BookId);
  
          var deletedBooks = existingBooks.Except(updatedBooks, x =&gt; x.BookId);
  
          var modifiedBooks = updatedBooks.Except(addedBooks, x =&gt; x.BookId);
  
          addedBooks.ToList&lt;Book&gt;().ForEach(x =&gt; UnitOfWork.Context.Entry(x).State = EntityState.Added);
  
          deletedBooks.ToList&lt;Book&gt;().ForEach(x =&gt; UnitOfWork.Context.Entry(x).State = EntityState.Deleted);
  
          foreach (var book in modifiedBooks)
          {
              var existingBook = UnitOfWork.Context.Set&lt;Book&gt;().Find(book.BookId);
  
              if (existingBook != null)
              {
                  var contextBook = UnitOfWork.Context.Entry(existingBook);
                  contextBook.CurrentValues.SetValues(book);
              }
          }
  
      UnitOfWork.Context.SaveChanges();
    }
  </code></pre>
  
  <p>And this works fine, but it seems a lot of code just to handle something trivial as an update of a collection, I don't want to do this for each collection I have in my model when I want to update it.</p>
  
  <p><strong>My question is: Is there a simplified way to handle one-to-many relationship updates in Entity Framework without changing the table schema, I mean without adding a Identifying Relationship?</strong></p>