private static bool IsSourceReferenceChanged(ObjectStateEntry entry, EntityReference reference) { var relationship = (AssociationSet)reference.RelationshipSet; var constraint = relationship.ElementType.Constraint; if (constraint.ToRole.Name == reference.TargetRoleName) { throw new InvalidOperationException("Dependant end expected."); } return(constraint.ToProperties.Any(property => entry.IsPropertyChanged(property.Name))); }
public bool IsPropertyChanged(string propertyName) { return(_stateEntry.IsPropertyChanged(propertyName)); }
private List <Tuple <string, object, object> > GetForeignKeyLabels(ObjectContext context, ObjectStateEntry oce) { List <Tuple <string, object, object> > items = new List <Tuple <string, object, object> >(); //FIND FOREIGN KEYS,GET THOSE FOREIGN KEY ENTITY, GET THEIR ENTITY LABELS var navigations = ((EntityType)oce.EntitySet.ElementType).DeclaredNavigationProperties; //INCLUDE THESE ENTITY LABELS IN MODIFIED PROPERTIES, SO THAT IT GETS LOGGED foreach (var navigation in navigations) { var rel = oce.RelationshipManager.GetRelatedEnd(navigation.RelationshipType.FullName, navigation.ToEndMember.Name); //&& rel.IsLoaded if (rel != null && rel is EntityReference) { var reference = (rel as EntityReference); //for added, deleted entities, we need to retrieve all the foreign objects //but for changed entities, we only need to retrieve the foreign objects //if the foreign key it self has changed on the object if (oce.State == EntityState.Modified) { //check if any of the modified property is part of this foreign key if (reference.EntityKey.EntityKeyValues.Select(kv => kv.Key).Intersect(oce.GetModifiedProperties().Where(prop => oce.IsPropertyChanged(prop))).Count() <= 0) { continue; } } object entity; //if the object is being deleted, retrieve with a special call to TryGetObjectByKey if (oce.State == EntityState.Deleted) { context.TryGetObjectByKey(oce, rel, out entity); } else { rel.Load(); entity = reference.GetType().GetProperty("Value").GetValue(reference); } object oldEntity; //IF THE OBJECT IS ADDED OR DETACHED THERE IS NO ORIGINAL VALUES var gotOldEntity = !(oce.State == EntityState.Added || oce.State == EntityState.Detached || oce.State == EntityState.Deleted); if (gotOldEntity) { //CHECK IF WE CAN GET BACK ORIGINAL VALUES var originalKeys = reference.EntityKey.EntityKeyValues.Select(kv => new EntityKeyMember(kv.Key, oce.OriginalValues[kv.Key])); gotOldEntity = context.TryGetObjectByKey(new System.Data.Entity.Core.EntityKey(reference.EntityKey.EntityContainerName + "." + reference.EntityKey.EntitySetName, originalKeys), out oldEntity); //WRITE ORIGINAL VALUES, ONLY IF WE GOT BACK IT SUCCESSFULLY entity.GetType().GetProperties().Where(y => y.GetCustomAttributes(true).Any(z => z is EntityLabelAttribute)).ToList().ForEach(r => items.Add(new Tuple <string, object, object>(r.Name, gotOldEntity ? r.GetValue(oldEntity) : "", r.GetValue(entity)))); } else if (oce.State == EntityState.Deleted) { entity.GetType().GetProperties().Where(y => y.GetCustomAttributes(true).Any(z => z is EntityLabelAttribute)).ToList().ForEach(r => items.Add(new Tuple <string, object, object>(r.Name, r.GetValue(entity), ""))); } else { //IF NOT, WRITE EMPTY STRINGS FOR ORIGINAL VALUES entity.GetType().GetProperties().Where(y => y.GetCustomAttributes(true).Any(z => z is EntityLabelAttribute)).ToList().ForEach(r => items.Add(new Tuple <string, object, object>(r.Name, "", r.GetValue(entity)))); } } } return(items); }