Reputation: 19702
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.
Upvotes: 5
Views: 1305
Reputation: 758
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...
}
}
}
Upvotes: 1
Reputation: 1701
You can access the two EntityKey objects through the CurrentValues property of a RelationshipEntry (derives from ObjectStateEntry). Should give you what you need.
Upvotes: 0