Пример #1
0
        //public static void MergeTracking<TEntity>(this System.Collections.IEnumerable target, System.Collections.IEnumerable source)
        //{
        //    //Go through the new data and apply any modifications to the target.
        //    foreach (ITrackableObject targetItem in target)
        //    {
        //        ITrackableObject sourceItem = null;

        //        if (source != null)
        //            sourceItem = source.FirstOrDefault(item => item.Id == targetItem.Id);

        //        if (sourceItem != null)
        //        {
        //            targetItem.MergeTracking(sourceItem);
        //        }
        //        else
        //        {
        //            targetItem.StartTracking();
        //        }
        //    }

        //    //Go through the deleted items and apply them to the new data.
        //    if (source != null)
        //    {
        //        foreach (ITrackableObject sourceItem in source.Where(item => item.IsDeleted()))
        //        {
        //            ITrackableObject targetItem = target.FirstOrDefault(item => item.Id == sourceItem.Id);
        //            if (targetItem != null)
        //            {
        //                targetItem.Delete();
        //            }
        //        }
        //    }

        //    ////Go through the added items and apply them to the new data.
        //    //if (source != null)
        //    //{
        //    //    foreach (ITrackableObject sourceItem in source.Where(item => item.IsNew()))
        //    //    {
        //    //        target.Add((TEntity)sourceItem);
        //    //    }
        //    //}

        //    return target;
        //}

        public static TrackingState MergeTracking(this ITrackableObject target, ITrackableObject source)
        {
            TrackingState targetTracker = new TrackingState(target);
            TrackingState sourceTracker = GetTracker(source);

            foreach (var property in target.GetType().GetProperties())
            {
                if (property.PropertyType != typeof(TrackingState) && ShouldAllowProperty(property))
                {
                    targetTracker.UnmodifiedState.Add(property, property.GetValue(target));

                    if (property.PropertyType.IsGenericType && property.PropertyType.IsAssignableTo(typeof(System.Collections.IEnumerable)))
                    {
                        dynamic targetList = property.GetValue(target);
                        if (targetList != null)
                        {
                            dynamic sourceList = property.GetValue(source);
                            MergeTracking(targetList, sourceList);
                        }
                    }
                    else if (property.PropertyType.IsAssignableTo(typeof(ITrackableObject)))
                    {
                        ITrackableObject sourceItem = property.GetValue(source) as ITrackableObject;
                        if (sourceItem != null)
                        {
                            if (sourceItem.IsNew() || sourceItem.IsDeleted())
                            {
                                property.SetValue(target, sourceItem);
                            }
                            else
                            {
                                ITrackableObject trackedItem = property.GetValue(target) as ITrackableObject;
                                if (trackedItem != null)
                                {
                                    trackedItem.MergeTracking(sourceItem);
                                }
                            }
                        }
                    }
                    else if (sourceTracker.UnmodifiedState.TryGetValue(property, out object sourceUnmodifiedValue))
                    {
                        if (IsPropertyModified(source, property, sourceUnmodifiedValue))
                        {
                            property.SetValue(target, property.GetValue(source));
                        }
                    }
                }
            }

            trackedObjects[target] = targetTracker;
            return(targetTracker);
        }
Пример #2
0
        private static TrackingState StartTracking(ITrackableObject source, TrackingCache cache)
        {
            TrackingState tracker = new TrackingState(source);

            PropertyInfo[] properties;
            if (!cache.Properties.TryGetValue(source.GetType(), out properties))
            {
                properties = source.GetType().GetProperties();
                cache.Properties[source.GetType()] = properties;
            }

            foreach (var property in properties)
            {
                if (property.PropertyType != typeof(TrackingState) && ShouldAllowProperty(property, cache))
                {
                    var value = property.GetValue(source);

                    if (property.PropertyType.IsGenericType && property.PropertyType.IsAssignableTo(typeof(System.Collections.IEnumerable)))
                    {
                        System.Collections.IEnumerable list = (System.Collections.IEnumerable)value;


                        List <ITrackableObject> deletedItems = new List <ITrackableObject>();
                        foreach (object item in list)
                        {
                            ITrackableObject trackedItem = item as ITrackableObject;
                            if (trackedItem != null)
                            {
                                if (trackedItem.IsTracking() && trackedItem.IsDeleted())
                                {
                                    deletedItems.Add(trackedItem);
                                    StopTracking(trackedItem);
                                }
                                else
                                {
                                    StartTracking(trackedItem, cache);
                                }
                            }
                        }

                        //Remove any items we detected as having been deleted.
                        IList editableList = list as IList;
                        if (editableList != null)
                        {
                            foreach (var removeItem in deletedItems)
                            {
                                editableList.Remove(removeItem);
                            }
                        }
                    }
                    else if (property.PropertyType.IsAssignableTo(typeof(ITrackableObject)))
                    {
                        ITrackableObject trackedItem = value as ITrackableObject;
                        if (trackedItem != null)
                        {
                            StartTracking(trackedItem, cache);
                        }
                    }

                    tracker.UnmodifiedState.Add(property, value);
                }
            }

            trackedObjects[source] = tracker;
            return(tracker);
        }