title: Entity Framework 6: detect relationship changes
body: <p>in my DbContext subclass I have overridden the SaveChanges() method so I can implement a sort of Trigger-like functionality (before the changes are actually saved).
  Now, in some of these triggers it is necessary to detect whether certain relationships have changed, regardless of many-to-many, one-to-one/zero etc.</p>
  
  <p>I have read a number of posts on the internet, including some on this site, that mention that the DbContext API doesn't expose any means of getting relationship info.
  However, ObjectContext should be able to.</p>
  
  <p>My SaveChanges method:</p>
  
  <pre><code>public override int SaveChanges()
  {
      IEntity entity;
      ChangeTracker.DetectChanges();
  
      var stateManager = ((IObjectContextAdapter)this).ObjectContext.ObjectStateManager;
      var added = stateManager.GetObjectStateEntries(EntityState.Added).ToList();
      var updated = stateManager.GetObjectStateEntries(EntityState.Modified).ToList();
      var deleted = stateManager.GetObjectStateEntries(EntityState.Deleted).ToList();
      var unchanged = stateManager.GetObjectStateEntries(EntityState.Unchanged).ToList();
  
      while ((entity = _entitiesRequiringTriggering.FirstOrDefault(x =&gt; x.Value).Key) != null)
      {
          _entitiesRequiringTriggering[entity] = false;
          var entry = ChangeTracker.Entries&lt;IEntity&gt;().SingleOrDefault(x =&gt; x.State != EntityState.Unchanged &amp;&amp; x.Entity == entity);
          if (entry == null) continue;
          var trigger = Triggers.Triggers.GetTriggerForEntity(entry.Entity, this);
          if (trigger == null) continue;
          trigger.BeforeSave(entry.Entity);
          switch (entry.State)
          {
              case EntityState.Added:
                  trigger.BeforeAdd(entry.Entity);
                  break;
              case EntityState.Modified:
                  trigger.BeforeUpdate(entry.Entity);
                  break;
              case EntityState.Deleted:
                  trigger.BeforeDelete(entry.Entity);
                  break;
          }
      }
      return base.SaveChanges();
  }
  </code></pre>
  
  <p>Note the four variables <strong>added</strong>, <strong>updated</strong>, <strong>deleted</strong> and <strong>unchanged</strong>.
  According to what I've found so far, the GetObjectStateEntries is supposed to return a collection of ObjectStateEntry, which has a property IsRelationship.</p>
  
  <p>I run the following code in a test application:</p>
  
  <pre><code>using (var db = container.Resolve&lt;IDatabaseContext&gt;())
  {
      var cus = db.Query&lt;Customer&gt;().Single(x =&gt; x.Id == 1);
      var newAddress = db.Query&lt;Address&gt;().Single(x =&gt; x.Id == 5);
  
      cus.Address = newAddress; //also sets the foreign key property Customer.AddressId to its new corresponding value
      db.SaveChanges();
  }
  </code></pre>
  
  <p>When I inspect the code in SaveChanges after that call, I get what was expected:
  one result in the <strong>updated</strong> list, the Customer object.
  But at no point do I ever get an ObjectStateEntry for the relationship (one-to-one) Customer_Address.</p>
  
  <p>I need to be able to detect as previously described when the relationship has changed.
  For normal scalar properties you would do this:</p>
  
  <pre><code>var changed = DbEntry.Property(x =&gt; x.Name).OriginalValue == DbEntry.Property(x =&gt; x.Name).CurrentValue;
  </code></pre>
  
  <p>But for reference properties that doesn't work obviously.
  Any ideas?</p>