Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF4 Audit changes of many to many relationships

I am in the process of adding auditing into my EF4 (model first) application. I can get the details about the structural properties on entities that have changes. I can also see when there have been changes on a many to many relationship. I can see the name of the types involved and what happened (add or remove) but what I'd really like is the Id's of the entities that are involved in the relationship change.

Here is what I currently have for tracking changes to many to many relationships:

var changes = context.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Deleted | EntityState.Modified);
var auditTime = DateTime.Now;

foreach (var change in changes)
{
    if (change.Entity != null && change.Entity.GetType().Equals(typeof(AuditTrail)))
    {
        continue;
    }

    var detailsBuilder = new StringBuilder();

    if (change.Entity == null & (change.State == EntityState.Added | change.State == EntityState.Deleted))
    {
        detailsBuilder.Append("A link between entities ");
        foreach (var changedMember in change.EntitySet.ElementType.KeyMembers)
        {
            detailsBuilder.AppendFormat("{0}", changedMember.Name);
            if(change.EntitySet.ElementType.KeyMembers.IndexOf(changedMember) < change.EntitySet.ElementType.KeyMembers.Count -2)
            {
                detailsBuilder.Append(", ");
            }
            else if (change.EntitySet.ElementType.KeyMembers.IndexOf(changedMember) == change.EntitySet.ElementType.KeyMembers.Count - 2)
            {
                detailsBuilder.Append(" and ");
            }
        }

        detailsBuilder.AppendFormat(" was {0}.<br />", change.State);
    }
}

How can I get the details (or even the actual entities) involved in the relationship change?

UPDATE

After poking around on for a few more hours I have managed to find the information I need (see attached image). However, the classes that store the data are internal sealed classes and I can't find a public entry to query the object state manager to get this information out back. So I can audit the change.

alt text

like image 820
ilivewithian Avatar asked Nov 15 '22 04:11

ilivewithian


1 Answers

This might help you out:

IEnumerable<IRelatedEnd> relatedEnds = ((IEntityWithRelationships) change.Entity).RelationshipManager.GetAllRelatedEnds();
foreach (var relatedEnd in relatedEnds)
{
     foreach (var subEntity in relatedEnd)
     {
          if (subEntity is IEntityWithRelationships)
          {
             var entityAssociated = (IEntityWithRelationships)subEntity;
             // Now you have your associated entity to work with...
          }
      }
 }
like image 144
lcrepas Avatar answered Nov 16 '22 22:11

lcrepas