title: ChangeTracker Entity Framework 4.1 - Original Values of Related Objects
body: <p>I have a base class that I inherit from that has two zero to many relationships with other entities:</p>
  
  <pre><code>public abstract class WebObject
  {
      public WebObject()
      {
          RelatedTags = new List&lt;Tag&gt;();
          RelatedWebObjects = new List&lt;WebObject&gt;();
      }
  
      [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
      public Guid Id { get; set; }
  
      public string MetaKeywords { get; set; }
      public string MetaDescription { get; set; }
  
      [InverseProperty("WebObjects")]
      public virtual WebSite WebSite { get; set; }
  
      [Required(ErrorMessage = "Every WebObject must be associated with a WebSite.")]
      public Guid WebSiteId { get; set; }
  
      public virtual ICollection&lt;Tag&gt; RelatedTags { get; set; }
      public IList&lt;Guid&gt; RelatedTagIds { get; set; }
      public virtual ICollection&lt;WebObject&gt; RelatedWebObjects { get; set; }
      public IList&lt;Guid&gt; RelatedWebObjectIds { get; set; }
  }
  </code></pre>
  
  <p>I am having difficulty getting the original values for these relationships (RelatedWebObjects &amp; RelatedTags) when looking at the entities using ChangeTracker during SaveChanges. I can see all of the scalar values before and after, and I can see the new relationships, but I cannot see the old ones. I've tried using the Member and Collection methods, but those only show me the current values; not the old. Also I don't like using those because it requires me to know the name of the navigation property, which isn't generic enough. </p>
  
  <p>I can find the related objects whose relationship is being changed, but of course the values within those related objects isn't changing, so that isn't any help either.</p>
  
  <p>Is there some clean way for me to track the previous relationships of an entity during SaveChanges with ChangeTracker?</p>
  
  <p>Below is the section of code that I'm working on:</p>
  
  <pre><code>    public override int SaveChanges()
      {
          List&lt;AuditObject&gt; auditTrailList = new List&lt;AuditObject&gt;();
  
          foreach (DbEntityEntry entity in ChangeTracker.Entries().Where(obj =&gt; { return obj.State == EntityState.Added || obj.State == EntityState.Modified || obj.State == EntityState.Deleted; }))
          {
              if (!(entity.Entity is AuditObject))
              {
                  AuditObject auditObject = new AuditObject();
  
                  auditObject.Id = Guid.NewGuid();
  
                  auditObject.RevisionStamp = DateTime.Now;
  
                  auditObject.UserName = HttpContext.Current.User.Identity.Name;
  
                  auditObject.EntityType = Utilities.GetCleanClassNameIfProxyClass(entity.Entity.GetType().Name);
  
                  if (entity.State == EntityState.Added)
                      auditObject.Action = EntityState.Added.ToString();
                  else if (entity.State == EntityState.Modified)
                      auditObject.Action = EntityState.Modified.ToString();
                  else if (entity.State == EntityState.Deleted)
                      auditObject.Action = EntityState.Deleted.ToString();
  
                  DbMemberEntry t1 = entity.Member("RelatedWebObjects");
                  // cannot find original relationship collection...
  
                  DbCollectionEntry t2 = entity.Collection("RelatedWebObjects");
                  // cannot find original relationship collection...
  
                  if (entity.State == EntityState.Added || entity.State == EntityState.Modified)
                  {
                      XDocument currentValues = new XDocument(new XElement(auditObject.EntityType));
  
                      foreach (string propertyName in entity.CurrentValues.PropertyNames)
                      {
                          currentValues.Root.Add(new XElement(propertyName, entity.CurrentValues[propertyName]));
                      }
  
                      auditObject.NewData = Regex.Replace(currentValues.ToString(), @"\r\n+", " ");
                  }
  
                  if (entity.State == EntityState.Modified || entity.State == EntityState.Deleted)
                  {
                      XDocument originalValues = new XDocument(new XElement(auditObject.EntityType));
  
                      foreach (string propertyName in entity.OriginalValues.PropertyNames)
                      {
                          originalValues.Root.Add(new XElement(propertyName, entity.OriginalValues[propertyName]));
                      }
  
                      auditObject.OldData = Regex.Replace(originalValues.ToString(), @"\r\n+", " ");
                  }
  
                  auditTrailList.Add(auditObject);
              }
          }
  
          foreach (var audit in auditTrailList)
              this.AuditObjects.Add(audit);
  
          return base.SaveChanges();
      }
  </code></pre>