title: Entity Framework ObjectStateEntry, get property of relation
body: <p>I am working on a change analyzer for Entity Framework and have one small problem left.</p>
  
  <p>I need to get the Property (<code>PropertyInfo</code>) of the parent in a relation (1-1, 1-n, n-n). </p>
  
  <p>Right now I can see the relation, the parent and the related entries, but I cannot seem to get the actual property of the object. The problem as I see it is that the relation knows about the keys, which are PKs and FKs and not the property that was responsible for the relation in the first place. In my solution now, I use the EntitySet name from the related entity, but that just isn't good enough. </p>
  
  <p>Here is the code that resolves the relations. I've left out the entity objects as well as the non relational analyzing parts. The <code>IHaveLogEntries</code> interface is to be implemented on Entities that want to be analyzed.</p>
  
  <p>Also, this code runs in <code>DbContext.SaveChanges()</code></p>
  
  <pre><code>this.ChangeTracker.DetectChanges();
  
  var objectContext = ((IObjectContextAdapter)this).ObjectContext;
  
  var entityEntries = objectContext.ObjectStateManager
      .GetObjectStateEntries(EntityState.Unchanged | EntityState.Modified | EntityState.Added)
      .ToList();
  
  var relationEntries = objectContext.ObjectStateManager
      .GetObjectStateEntries(EntityState.Added | EntityState.Deleted)
      .ToList();
  
  var q = from relationEntry in relationEntries
      from entityEntry in entityEntries
      where relationEntry.IsRelationshipForKey(entityEntry.EntityKey)
      where !(entityEntry.Entity is IHaveLogEntries)
      let otherEndKey = relationEntry.OtherEndKey(entityEntry.EntityKey)
      let logEntryEntity = entityEntries
          .Where(e =&gt; e.EntityKey == otherEndKey)
          .Select(se =&gt; se.Entity)
          .Cast&lt;IHaveLogEntries&gt;()
          .Single()
      let combined = new
      {
          RelationEntry = relationEntry,
          EntityEntry = entityEntry,
          LogEntryEntity = logEntryEntity
      }
      group combined by 
          new { combined.LogEntryEntity, combined.EntityEntry.EntitySet.Name }
          into combinedGroup
          let added = combinedGroup
              .Where(c =&gt; c.RelationEntry.State == EntityState.Added)
              .Select(c =&gt; c.EntityEntry.Entity.ToString())
          let deleted = combinedGroup
              .Where(c =&gt; c.RelationEntry.State == EntityState.Deleted)
              .Select(c =&gt; c.EntityEntry.Entity.ToString())
          select new
          {
              combinedGroup.Key.LogEntryEntity,
              Field = combinedGroup.Key.Name,
              Operation = Operation.Modified,
              FromValue = (object)string.Join(",", deleted.ToArray()),
              ToValue = (object)string.Join(",", added.ToArray())
          };
  
  var l = q.ToList();
  </code></pre>
  
  <p>The main problem is where I group the result, where I use <code>combined.EntityEntry.EntitySet.Name</code>. I would like to figure out the name of the property on the <code>IHaveLogEntries</code> entity instead if that is possible. That entity would be the <code>combined.LogEntryEntity</code> in this case.</p>
  
  <p>Thankful for your input.</p>