Example #1
0
        public When_loading_entities_with_include()
        {
            dataServiceMock = new Mock <ISimpleParentChildDataService>();

            context = new SimpleParentChildDataContext(() => dataServiceMock.Object);

            dataServiceMock.Setup(x => x.GetChildSet(null, It.IsAny <Query>()))
            .Returns <ClientInfo, Query>((ci, q) =>
            {
                var child = new Child {
                    Id = 20, Parent = new Parent {
                        Id = 10
                    }
                };
                child.AcceptChanges();
                child.Parent.AcceptChanges();

                return(new QueryResult <Child> {
                    Data = new[] { child }
                });
            });

            dataServiceMock.Setup(x => x.GetParentSet(null, It.IsAny <Query>()))
            .Returns <ClientInfo, Query>((ci, q) =>
            {
                var parent = new Parent {
                    Id = 10
                };
                parent.AcceptChanges();

                return(new QueryResult <Parent> {
                    Data = new[] { parent }
                });
            });
        }
        public When_detaching_entities()
        {
            context = new SimpleParentChildDataContext(() => default(ISimpleParentChildDataService));

            parent = new Parent();
            child  = new Child {
                Parent = parent
            };

            parent.AcceptChanges();
            child.AcceptChanges();

            context.Attach(parent);
        }
Example #3
0
        public void Query_result_with_include_collection_should_be_substituted_with_local_instance()
        {
            dataServiceMock.Setup(x => x.GetChildSet(null, It.IsAny <Query>()))
            .Returns <ClientInfo, Query>((ci, q) =>
            {
                var child = new Child {
                    Id = 20
                };
                child.AcceptChanges();

                return(new QueryResult <Child> {
                    Data = new[] { child }
                });
            });

            dataServiceMock.Setup(x => x.GetParentSet(null, It.IsAny <Query>()))
            .Returns <ClientInfo, Query>((ci, q) =>
            {
                var child = new Child {
                    Id = 20, Parent = new Parent {
                        Id = 10
                    }
                };
                child.AcceptChanges();
                child.Parent.AcceptChanges();

                return(new QueryResult <Parent> {
                    Data = new[] { child.Parent }
                });
            });

            var child0 = context.ChildSet.AsQueryable().Single();

            var parent = context.ParentSet.AsQueryable().Include("Children").Single();

            var child1 = parent.Children.Single();

            child0.ShouldBeSameAs(child1);

            dataServiceMock.Verify(x => x.GetChildSet(null, It.IsAny <Query>()), Times.Once);
            dataServiceMock.Verify(x => x.GetParentSet(null, It.IsAny <Query>()), Times.Once);
        }
Example #4
0
        private Child AttachWithRelations(Child entity, InsertMode insertMode = InsertMode.Attach, MergeOption mergeOption = MergeOption.AppendOnly, List <object> referenceTrackingList = null)
        {
            #region iteration tracking

            if (ReferenceEquals(null, referenceTrackingList))
            {
                referenceTrackingList = new List <object>();
            }

            if (referenceTrackingList.Contains(entity))
            {
                return(_childSet.GetExisting(entity));
            }
            else
            {
                referenceTrackingList.Add(entity);
            }

            #endregion

            #region add/attach entity

            Child existingEntity = null;

            switch (insertMode)
            {
            case InsertMode.Add:
                existingEntity = _childSet.Add(entity);
                break;

            case InsertMode.Attach:
                existingEntity = _childSet.Attach(entity);
                break;

            default:
                throw new Exception(string.Format("Implementation Exception: missing action for {0}", insertMode));
            }

            if (!ReferenceEquals(null, existingEntity) && ReferenceEquals(existingEntity, entity))
            {
                return(existingEntity);
            }

            #endregion

            #region attach relations recursively

            // register entity's property changed event if entity is new to context
            if (ReferenceEquals(null, existingEntity))
            {
                entity.PropertyChanged += On_child_propertyChanged;
            }

            // attach related entity to context
            if (!ReferenceEquals(null, entity.Parent))
            {
                var existingRelatedEntity = AttachWithRelations(entity.Parent, insertMode, mergeOption, referenceTrackingList);

                // update relation if entity is new to context or relation is new to entity
                if (ReferenceEquals(null, existingEntity) || !entity.Parent.Equals(existingEntity.Parent))
                {
                    if (!ReferenceEquals(null, existingRelatedEntity) && !ReferenceEquals(existingRelatedEntity, entity.Parent))
                    {
                        // check merge options
                        if (!(mergeOption == MergeOption.PreserveChanges && existingRelatedEntity.ChangeTracker.OriginalValues.ContainsKey("Children")))
                        {
                            using (entity.ChangeTrackingPrevention())
                            {
                                entity.Parent = existingRelatedEntity;
                            }

                            using (existingRelatedEntity.ChangeTrackingPrevention())
                            {
                                var entityToReplace = existingRelatedEntity.Children.FirstOrDefault(e => e.Equals(entity));
                                if (!ReferenceEquals(null, entityToReplace))
                                {
                                    using (entityToReplace.ChangeTrackingPrevention())
                                    {
                                        existingRelatedEntity.Children.Remove(entityToReplace);
                                    }
                                }

                                existingRelatedEntity.Children.Add(entity);
                            }
                        }
                    }
                }
            }

            #endregion

            #region refresh existing entity based on merge options

            if (!ReferenceEquals(null, existingEntity) && !ReferenceEquals(existingEntity, entity))
            {
                if (ChildSet.MergeOption == MergeOption.OverwriteChanges)
                {
                    Invoke(delegate
                    {
                        existingEntity.Refresh(entity, trackChanges: false);
                        existingEntity.AcceptChanges();
                    });
                }
                else if (ChildSet.MergeOption == MergeOption.PreserveChanges)
                {
                    Invoke(delegate
                    {
                        existingEntity.Refresh(entity, trackChanges: false, preserveExistingChanges: true);
                    });
                }
            }

            #endregion

            return(existingEntity);
        }