none
Tracking changes to independent associations RRS feed

  • General discussion

  • Entity framework makes it easy to track changes to relationships between two entities. The following will return ObjectStateEntry instances for all added and deleted relationships:

    ObjectStateManager.GetObjectStateEntries(
        EntityState.Added | EntityState.Deleted)
        .Where(e => e.IsRelationship);
    
    For audit purposes I want to retrieve the following information about each association end:
    • navigation property name (if any)
    • multiplicity

    For added associations ObjectStateEntry instance contains EntityKey objects for both entities involved in the relationship:

    var key0 = entry.CurrentValues[0] as EntityKey;
    var key1 = entry.CurrentValues[1] as EntityKey;
    
    It also references the type that represents current relationships:
    var relationshipType = objectStateEntry.EntitySet.ElementType;
    
    What I am trying to do is map each entity key (key0, key1) to the appropriate ends of association (relationshipType.KeyMembers). The only way to do this as far as I can tell is to look at the referenced type of each association end and match it with the type of the entity represented by an entity key. However, this will not work if the both ends of an association reference the same entity type (think employee entity with manager FK that references another employee).

    So here are helper functions that I got so far to get navigation property name and multiplicity of a relationship end. Is there a better way to do the same?

    public static string GetNavigationPropertyName(
      this ObjectStateEntry entry, EntityKey key)
    {
     var relationshipType = entry.EntitySet.ElementType;
     var entitySet = key.GetEntitySet(
       entry.ObjectStateManager.MetadataWorkspace);
     var property = entitySet.ElementType.NavigationProperties.Where(
       p => p.RelationshipType == relationshipType)
       .SingleOrDefault();
    
     if (property == null)
     {
      return null;
     }
    
     return property.Name;
    }
    
    public static RelationshipMultiplicity GetAssociationEndMultiplicity(
      this ObjectStateEntry entry, EntityKey key)
    {
     var relationshipType = entry.EntitySet.ElementType;
    
     var entitySet = key.GetEntitySet(
       entry.ObjectStateManager.MetadataWorkspace);
    
     foreach (EdmMember member in relationshipType.KeyMembers)
     {
      var refType = member.TypeUsage.EdmType as RefType;
      if (refType.ElementType == entitySet.ElementType)
      {
       var relEndMember = member as RelationshipEndMember;
       return relEndMember.RelationshipMultiplicity;
      }
     }
     throw new InvalidOperationException(
       "couldn't find association end");
    }
    
    Any suggestions/ideas are welcome.

    Thanks, Daniel



    Tuesday, June 14, 2011 3:56 PM

All replies

  • Hello Daniel,

    Thanks for your post.

    I think it's more suitable to change your thread type to discussion. What do you think of this? If you agree with me, I will change it for you.

    Thanks for your understanding and support.

     

    Have a nice day,


    Jackie Sun [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, June 16, 2011 9:51 AM
    Moderator