title: Difference between DbSet.Remove and DbContext.Entry(entity).State = EntityState.Deleted
body: <p>Consider the following entity model:</p>
  
  <pre><code>public class Agreement : Entity
  {
      public int AgreementId { get; set; }
      public virtual ICollection&lt;Participant&gt; Participants { get; set; }
  }
  
  public class Establishment : Entity
  {
      public int EstablishmentId { get; set; }
  }
  
  public class Participant : Entity
  {
      public int AgreementId { get; set; }
      public virtual Agreement Agreement { get; set; }
  
      public int EstablishmentId { get; set; }
      public virtual Establishment { get; set; }
  
      public bool IsOwner { get; set; }
  }
  </code></pre>
  
  <p>The reason there is not a direct <code>ICollection&lt;Establishment&gt;</code> on the Agreement entity is because of the IsOwner property, which further defines this many-to-many relationship.</p>
  
  <p>The relationship is mapped like so:</p>
  
  <pre><code>internal ParticipantOrm()
  {
      ToTable(typeof(Participant).Name);
  
      HasKey(k =&gt; new { k.AgreementId, k.EstablishmentId });
  
      HasRequired(d =&gt; d.Agreement)
          .WithMany(p =&gt; p.Participants)
          .HasForeignKey(d =&gt; d.AgreementId)
          .WillCascadeOnDelete(true);
  
      HasRequired(d =&gt; d.Establishment)
          .WithMany()
          .HasForeignKey(d =&gt; d.EstablishmentId)
          .WillCascadeOnDelete(true);
  }
  </code></pre>
  
  <p>The relationship is uni-directional, meaning you can only get to the Participants from within an Agreement -- you cannot access the agreements from the Establishment.</p>
  
  <p>Now, since the Agreement entity's primary key is part of the gerund Participant's primary key, and since cascade delete is specified, I would expect that putting the Agreement into the Deleted state would also cause each entity in its Participants collection to also be put into the deleted state.</p>
  
  <p>This appears to work when calling Remove on an Agreement DbSet:</p>
  
  <pre><code>// this works
  dbContext.Agreements.Remove(agreement);
  dbContext.SaveChanges();
  </code></pre>
  
  <p>However, it does not appear to work when simply setting the agreement entry's state to deleted:</p>
  
  <pre><code>// this causes an exception when Participants is not empty
  dbContext.Entry(agreement).State = EntityState.Deleted;
  dbContext.SaveChanges();
  </code></pre>
  
  <p><strong>Is there a way I can define the relationship so that simply putting the Agreement entity into the deleted state will also cause the corresponding collection item entities to be put into the deleted state?</strong></p>
  
  <p><strong>Update</strong></p>
  
  <p>I have been reading about this, and found out that eager loading the Participants collection does not help:</p>
  
  <pre><code>// eager loading does not help, this still breaks
  var agreement = dbContext.Set&lt;Agreement&gt;()
      .Include(a =&gt; a.Participants)
      .FirstOrDefault();
  dbContext.Entry(agreement).State = EntityState.Deleted;
  dbContext.SaveChanges();
  </code></pre>