private ObjectVisitationHelper(ObjectVisitationHelper other)
 {
     _objectSet = other._objectSet.ToDictionary(
         x => x.Key,
         y => y.Value,
         other._objectSet.Comparer);
 }
 private ObjectVisitationHelper(ObjectVisitationHelper other)
 {
     _objectSet = other._objectSet.ToDictionary(
         x => x.Key,
         y => y.Value,
         other._objectSet.Comparer);
 }
 /// <summary>
 /// Helper method which initializes the given reference to ObjectVisitationHelper
 /// if it is null.
 /// </summary>
 /// <param name="visitationHelper">Reference to ObjectVisitationHelper</param>
 public static void EnsureCreated(ref ObjectVisitationHelper visitationHelper)
 {
     if (visitationHelper == null)
     {
         visitationHelper = new ObjectVisitationHelper();
     }
 }
        // Recursively get modified properties
        public static IEnumerable<IEnumerable<string>> GetModifiedProperties
            (this ITrackable item, ObjectVisitationHelper visitationHelper = null)
        {
            // Prevent endless recursion
            ObjectVisitationHelper.EnsureCreated(ref visitationHelper);
            if (!visitationHelper.TryVisit(item)) yield break;

            foreach (var navProp in item.GetNavigationProperties())
            {
                foreach (var refProp in navProp.AsReferenceProperty())
                {
                    foreach (var modifiedProps in refProp.EntityReference.GetModifiedProperties(visitationHelper))
                    {
                        yield return modifiedProps;
                    }
                }

                foreach (var colProp in navProp.AsCollectionProperty())
                {
                    foreach (ITrackable child in colProp.EntityCollection)
                    {
                        foreach (var modifiedProps in child.GetModifiedProperties(visitationHelper))
                        {
                            yield return modifiedProps;
                        }
                    }
                }
            }
            yield return item.ModifiedProperties;
        }
        // Recursively get tracking states
        public static IEnumerable<TrackingState> GetTrackingStates
            (this ITrackable item, TrackingState? trackingState = null,
            ObjectVisitationHelper visitationHelper = null)
        {
            // Prevent endless recursion
            ObjectVisitationHelper.EnsureCreated(ref visitationHelper);
            if (!visitationHelper.TryVisit(item)) yield break;

            foreach (var navProp in item.GetNavigationProperties())
            {
                foreach (var refProp in navProp.AsReferenceProperty())
                {
                    foreach (var state in refProp.EntityReference.GetTrackingStates(visitationHelper: visitationHelper))
                    {
                        if (trackingState == null || state == trackingState)
                            yield return state;
                    }
                }

                foreach (var colProp in navProp.AsCollectionProperty())
                {
                    foreach (ITrackable child in colProp.EntityCollection)
                    {
                        foreach (var state in child.GetTrackingStates(visitationHelper: visitationHelper))
                        {
                            if (trackingState == null || state == trackingState)
                                yield return state;
                        }
                    }
                }
            }
            yield return item.TrackingState;
        }
        // Recursively set tracking state
        public static void SetTrackingState(this ITrackable item,
            TrackingState state, ObjectVisitationHelper visitationHelper = null)
        {
            // Prevent endless recursion
            ObjectVisitationHelper.EnsureCreated(ref visitationHelper);
            if (!visitationHelper.TryVisit(item)) return;

            foreach (var navProp in item.GetNavigationProperties())
            {
                foreach (var refProp in navProp.AsReferenceProperty())
                {
                    refProp.EntityReference.SetTrackingState(state, visitationHelper);
                    refProp.EntityReference.TrackingState = state;
                }

                foreach (var colProp in navProp.AsCollectionProperty())
                {
                    foreach (ITrackable child in colProp.EntityCollection)
                    {
                        child.SetTrackingState(state, visitationHelper);
                        child.TrackingState = state;
                    }
                }
            }
        }
Esempio n. 7
0
        private static void AcceptChanges(this ITrackable item, ObjectVisitationHelper visitationHelper)
        {
            ObjectVisitationHelper.EnsureCreated(ref visitationHelper);

            // Prevent endless recursion
            if (visitationHelper != null && !visitationHelper.TryVisit(item))
            {
                return;
            }

            // Set tracking state for child collections
            foreach (var navProp in item.GetNavigationProperties())
            {
                // Apply changes to 1-1 and M-1 properties
                foreach (var refProp in navProp.AsReferenceProperty())
                {
                    refProp.EntityReference.AcceptChanges(visitationHelper);
                }

                // Apply changes to 1-M properties
                foreach (var colProp in navProp.AsCollectionProperty <IList>())
                {
                    var items = colProp.EntityCollection;
                    var count = items.Count;
                    for (int i = count - 1; i > -1; i--)
                    {
                        // Stop recursion if trackable hasn't been visited
                        var trackable = items[i] as ITrackable;
                        if (trackable != null)
                        {
                            if (trackable.TrackingState == TrackingState.Deleted)
                            {
                                // Remove items marked as deleted
                                items.RemoveAt(i);
                            }
                            else
                            {
                                // Recursively accept changes on trackable
                                trackable.AcceptChanges(visitationHelper);
                            }
                        }
                    }
                }
            }

            // Set tracking state and clear modified properties
            item.TrackingState      = TrackingState.Unchanged;
            item.ModifiedProperties = null;
        }
        // Recursively get entity states
        public static IEnumerable<EntityState> GetEntityStates(this DbContext context,
            ITrackable item, EntityState? entityState = null,
            ObjectVisitationHelper visitationHelper = null)
        {
            // Prevent endless recursion
            ObjectVisitationHelper.EnsureCreated(ref visitationHelper);
            if (!visitationHelper.TryVisit(item)) yield break;

            foreach (var colProp in item.GetNavigationProperties().OfCollectionType())
            {
                foreach (ITrackable child in colProp.EntityCollection)
                {
                    foreach (var state in context.GetEntityStates(child, visitationHelper: visitationHelper))
                    {
                        if (entityState == null || state == entityState)
                            yield return state;
                    }
                }
            }
            yield return context.Entry(item).State;
        }
 /// <summary>
 /// Helper method which initializes the given reference to ObjectVisitationHelper
 /// if it is null.
 /// </summary>
 /// <param name="visitationHelper">Reference to ObjectVisitationHelper</param>
 public static void EnsureCreated(ref ObjectVisitationHelper visitationHelper)
 {
     if (visitationHelper == null)
         visitationHelper = new ObjectVisitationHelper();
 }