Esempio n. 1
0
 public static void Validate(Parent parent)
 {
     // Simulate a validation pass that enumerates all children.
     foreach (Child child in parent.Children)
     {
         foreach (GrandChild grandChild in child.Children)
         {
             GreatGrandChild greatGrandChild = grandChild.Child;
         }
     }
 }
Esempio n. 2
0
        public void DeleteParent(Parent parent)
        {
            // normally you wouldn't validate a deleted hierarchy,
            // but we do it here for test validation
            CompositionHelper.Validate(parent);

            ((CompositionEntityBase)parent).OperationResult = "Delete";

            // Delete all children in the hierarchy.
            foreach (Child child in parent.Children)
            {
                foreach (GrandChild grandChild in child.Children)
                {
                    GreatGrandChild greatGrandChild = grandChild.Child;
                    if (greatGrandChild != null)
                    {
                    }
                }
            }
        }
Esempio n. 3
0
        public void InsertParent(Parent parent)
        {
            // first validate the hierarchy
            CompositionHelper.Validate(parent);

            ((CompositionEntityBase)parent).OperationResult = "Insert";

            // for a new parent, all children will also be new
            // so we enumerate all and "add" them
            foreach (Child child in parent.Children)
            {
                ((CompositionEntityBase)child).OperationResult = "Insert";
                foreach (GrandChild grandChild in child.Children)
                {
                    ((CompositionEntityBase)grandChild).OperationResult = "Insert";
                    GreatGrandChild greatGrandChild = grandChild.Child;
                    if (greatGrandChild != null)
                    {
                        ((CompositionEntityBase)greatGrandChild).OperationResult = "Insert";
                    }
                }
            }
        }
        public void DeleteGreatGrandChild(GreatGrandChild greatGrandChild)
        {
            SetOperationInvoked(greatGrandChild);

            ((CompositionEntityBase)greatGrandChild).OperationResult = "Delete";
        }
Esempio n. 5
0
        public void UpdateParent(Parent parent)
        {
            // first validate the hierarchy
            CompositionHelper.Validate(parent);

            ((CompositionEntityBase)parent).OperationResult = "Update";

            // for an updated, children might be added, updated
            // or deleted. We need to enumerate all and act appropriately
            foreach (Child child in this.ChangeSet.GetAssociatedChanges(parent, p => p.Children))
            {
                ChangeOperation changeOp = this.ChangeSet.GetChangeOperation(child);
                if (changeOp == ChangeOperation.Insert)
                {
                    ((CompositionEntityBase)child).OperationResult = "Insert";
                }
                else if (changeOp == ChangeOperation.Update)
                {
                    ((CompositionEntityBase)child).OperationResult = "Update";
                }
                else if (changeOp == ChangeOperation.Delete)
                {
                    ((CompositionEntityBase)child).OperationResult = "Delete";
                }

                // now process child updates for the child
                foreach (GrandChild grandChild in this.ChangeSet.GetAssociatedChanges(child, p => p.Children))
                {
                    changeOp = this.ChangeSet.GetChangeOperation(grandChild);
                    if (changeOp == ChangeOperation.Insert)
                    {
                        ((CompositionEntityBase)grandChild).OperationResult = "Insert";
                    }
                    else if (changeOp == ChangeOperation.Update)
                    {
                        ((CompositionEntityBase)grandChild).OperationResult = "Update";
                    }
                    else if (changeOp == ChangeOperation.Delete)
                    {
                        ((CompositionEntityBase)grandChild).OperationResult = "Delete";
                    }

                    // finally, process any great grand child updates
                    GreatGrandChild updatedGreateGrandChild = this.ChangeSet.GetAssociatedChanges(grandChild, p => p.Child).Cast <GreatGrandChild>().SingleOrDefault();
                    if (updatedGreateGrandChild != null)
                    {
                        changeOp = this.ChangeSet.GetChangeOperation(updatedGreateGrandChild);
                        if (changeOp == ChangeOperation.Insert)
                        {
                            ((CompositionEntityBase)updatedGreateGrandChild).OperationResult = "Insert";
                        }
                        else if (changeOp == ChangeOperation.Update)
                        {
                            ((CompositionEntityBase)updatedGreateGrandChild).OperationResult = "Update";
                        }
                        else if (changeOp == ChangeOperation.Delete)
                        {
                            ((CompositionEntityBase)updatedGreateGrandChild).OperationResult = "Delete";
                        }
                    }
                }
            }
        }
Esempio n. 6
0
 public void CustomOp_GreatGrandChild(GreatGrandChild greatGrandChild)
 {
     this.SetOperationInvoked(greatGrandChild, "CustomOp_GreatGrandChild");
     ((CompositionEntityBase)greatGrandChild).OperationResult += ",CustomOp_GreatGrandChild";
 }
Esempio n. 7
0
        public void InsertGreatGrandChild(GreatGrandChild greatGrandChild)
        {
            SetOperationInvoked(greatGrandChild);

            ((CompositionEntityBase)greatGrandChild).OperationResult = "Insert";
        }
Esempio n. 8
0
        public void DeleteGreatGrandChild(GreatGrandChild greatGrandChild)
        {
            SetOperationInvoked(greatGrandChild);

            ((CompositionEntityBase)greatGrandChild).OperationResult = "Delete";
        }
        public void HierarchicalChangeTracking_ChildAssociationUpdates_EntityCollection()
        {
            CompositionScenarios_Explicit ctxt = new CompositionScenarios_Explicit(CompositionScenarios_Explicit_Uri);
            Parent parent = CreateCompositionHierarchy(3, 3);
            ctxt.Parents.Attach(parent);

            // Remove a child and add one
            Child c = parent.Children.First();
            GrandChild gc = c.Children.ToArray()[1];
            GreatGrandChild ggc = gc.Child;
            gc.Child = null;   // remove
            GrandChild newGc = new GrandChild
            {
                ID = 100
            };
            GreatGrandChild newGgc = new GreatGrandChild
            {
                ID = 100
            };
            c.Children.Add(newGc);   // add
            newGc.Child = newGgc; 
            Assert.IsTrue(parent.HasChanges);
            Assert.IsTrue(c.HasChanges);
            Assert.IsTrue(gc.HasChanges);
            Assert.IsFalse(ggc.HasChanges);
            Assert.AreEqual(EntityState.Deleted, ggc.EntityState);
            EntityChangeSet cs = ctxt.EntityContainer.GetChanges();
            Assert.IsTrue(cs.AddedEntities.Count == 2 && cs.ModifiedEntities.Count == 3 && cs.RemovedEntities.Count == 1);

            // Reject the remove and verify state
            ((IRevertibleChangeTracking)gc).RejectChanges();
            Assert.IsTrue(parent.HasChanges);
            Assert.IsTrue(c.HasChanges);
            Assert.IsFalse(gc.HasChanges);
            Assert.IsFalse(ggc.HasChanges);
            cs = ctxt.EntityContainer.GetChanges();
            Assert.IsTrue(cs.AddedEntities.Count == 2 && cs.ModifiedEntities.Count == 2 && cs.RemovedEntities.Count == 0);
            Assert.AreSame(ggc, gc.Child);

            ((IRevertibleChangeTracking)c).RejectChanges();
            cs = ctxt.EntityContainer.GetChanges();
            Assert.IsTrue(cs.AddedEntities.Count == 0 && cs.ModifiedEntities.Count == 0 && cs.RemovedEntities.Count == 0);
        }
 public void CustomOp_GreatGrandChild(GreatGrandChild greatGrandChild)
 {
     ((CompositionEntityBase)greatGrandChild).OperationResult += ",CustomOp_GreatGrandChild";
 }
        public void InsertGreatGrandChild(GreatGrandChild greatGrandChild)
        {
            SetOperationInvoked(greatGrandChild);

            ((CompositionEntityBase)greatGrandChild).OperationResult = "Insert";
        }
Esempio n. 12
0
 public void CustomOp_GreatGrandChild(GreatGrandChild greatGrandChild)
 {
     ((CompositionEntityBase)greatGrandChild).OperationResult += ",CustomOp_GreatGrandChild";
 }
 /// <summary>
 /// Invokes the 'CustomOp_GreatGrandChild' method of the specified <see cref="GreatGrandChild"/> entity.
 /// </summary>
 /// <param name="greatGrandChild">The <see cref="GreatGrandChild"/> entity instance.</param>
 public void CustomOp_GreatGrandChild(GreatGrandChild greatGrandChild)
 {
     greatGrandChild.CustomOp_GreatGrandChild();
 }
 private bool FilterChild(GreatGrandChild entity)
 {
     return (entity.ParentID == this.ID);
 }
        /// <summary>
        /// Make a bunch of multilevel updates to a hierarchy
        /// </summary>
        private void HierarchyUpdate(Uri testUri)
        {
            CompositionScenarios_Explicit ctxt = new CompositionScenarios_Explicit(testUri);

            Parent parent = null;
            SubmitOperation so = null;
            LoadOperation lo = ctxt.Load(ctxt.GetParentsQuery(), false);
            IEnumerable<Entity> expectedUpdates = null;

            EnqueueConditional(() => lo.IsComplete);
            EnqueueCallback(delegate
            {
                TestHelperMethods.AssertOperationSuccess(lo);

                parent = ctxt.Parents.First();
                Child existingChild = parent.Children.First();
                Assert.AreSame(parent, ((Entity)existingChild).Parent);
                GrandChild existingGrandChild = existingChild.Children.Skip(1).Take(1).Single();

                // add a few new children
                Child newChild = new Child
                {
                    ID = 100
                };
                parent.Children.Add(newChild);
                GrandChild newGc = new GrandChild
                {
                    ID = 100
                };
                existingChild.Children.Add(newGc);
                GreatGrandChild newGgc = new GreatGrandChild
                {
                    ID = 100
                };

                // update a few children
                GrandChild updatedGrandChild = existingChild.Children.First(p => p.EntityState != EntityState.New);
                updatedGrandChild.Property += "x";

                // remove a few children
                GreatGrandChild deletedGreatGrandChild = existingGrandChild.Child;
                existingGrandChild.Child = null;

                // invoke a custom method on the parent
                parent.CustomOp_Parent();

                EntityChangeSet cs = ctxt.EntityContainer.GetChanges();
                Assert.IsTrue(cs.AddedEntities.Count == 2 && cs.ModifiedEntities.Count == 4 && cs.RemovedEntities.Count == 1);
                Assert.IsTrue(cs.AddedEntities.Contains(newChild));
                Assert.IsTrue(cs.AddedEntities.Contains(newGc));
                Assert.IsTrue(cs.ModifiedEntities.Contains(parent));
                Assert.IsTrue(cs.ModifiedEntities.Contains(existingChild));
                Assert.IsTrue(cs.ModifiedEntities.Contains(existingGrandChild));
                Assert.IsTrue(cs.ModifiedEntities.Contains(updatedGrandChild));
                Assert.IsTrue(cs.RemovedEntities.Contains(deletedGreatGrandChild));

                // direct test verifying that we create the correct set of
                // ChangeSetEntries to send to the server
                int modifiedCount = cs.AddedEntities.Count + cs.ModifiedEntities.Count + cs.RemovedEntities.Count;
                int expectedOperationCount = 24;
                IEnumerable<ChangeSetEntry> entityOps = ChangeSetBuilder.Build(cs);
                int entityOpCount = entityOps.Count();
                Assert.AreEqual(expectedOperationCount, entityOpCount);
                Assert.AreEqual(expectedOperationCount - modifiedCount, entityOps.Count(p => p.Operation == EntityOperationType.None));

                // verify that original associations are set up correctly
                this.ValidateEntityOperationAssociations(entityOps);

                expectedUpdates = cs.Where(p => p.HasChildChanges || p.HasPropertyChanges).ToArray();
                so = ctxt.SubmitChanges(TestHelperMethods.DefaultOperationAction, null);
            });
            EnqueueConditional(() => so.IsComplete);
            EnqueueCallback(delegate
            {
                this.VerifySuccess(ctxt, so, expectedUpdates);

                // verify that the custom method was invoked
                string[] updateResults = parent.OperationResult.Split(',');
                Assert.IsTrue(updateResults.Contains("CustomOp_Parent"));
            });

            EnqueueTestComplete();
        }
        public void Composition_InvalidParentUpdate_EntityRef()
        {
            ConfigurableEntityContainer container = new ConfigurableEntityContainer();
            container.CreateSet<GrandChild>(EntitySetOperations.All);
            container.CreateSet<GreatGrandChild>(EntitySetOperations.All);
            EntitySet<GrandChild> parentSet = container.GetEntitySet<GrandChild>();
            EntitySet<GreatGrandChild> childSet = container.GetEntitySet<GreatGrandChild>();

            GrandChild parent1 = new GrandChild() { ID = 1 };
            GrandChild parent2 = new GrandChild() { ID = 2 };
            GreatGrandChild child = new GreatGrandChild() { ID = 1, Parent = parent1 };

            parentSet.Attach(parent1);
            parentSet.Attach(parent2);

            Assert.IsTrue(childSet.IsAttached(child), "Child was not attached automatically.");
            Assert.AreSame(parent1, ((Entity)child).Parent, "Entity.Parent doesn't reflect the parent-child relationship.");

            // point the child to a new parent, which results
            // in the child being reparented (an invalid update)
            child.Parent = parent2;

            EntityChangeSet changeSet = container.GetChanges();
            Assert.AreEqual(EntityState.Modified, child.EntityState);
            Assert.AreEqual(EntityState.Modified, parent1.EntityState);
            Assert.AreEqual(EntityState.Modified, parent2.EntityState);

            // Verify that changing the parent throws an exception when
            // changes are validated
            ExceptionHelper.ExpectInvalidOperationException(delegate
            {
                ChangeSetBuilder.CheckForInvalidUpdates(changeSet);
            }, string.Format(Resource.Entity_CantReparentComposedChild, child));
        }
        public void Composition_MultipleRemoveReadds()
        {
            ConfigurableEntityContainer container = new ConfigurableEntityContainer();
            container.CreateSet<Parent>(EntitySetOperations.All);
            container.CreateSet<Child>(EntitySetOperations.All);
            container.CreateSet<GrandChild>(EntitySetOperations.All);
            container.CreateSet<GreatGrandChild>(EntitySetOperations.All);
            EntitySet<Parent> parentSet = container.GetEntitySet<Parent>();
            EntitySet<Child> childSet = container.GetEntitySet<Child>();
            EntitySet<GreatGrandChild> ggChildSet = container.GetEntitySet<GreatGrandChild>();

            Parent parent = new Parent() { ID = 1 };
            Child child = new Child() { ID = 1, Parent = parent };
            container.LoadEntities(new Entity[] { parent, child });

            parent.Children.Remove(child);
            Assert.AreEqual(EntityState.Deleted, child.EntityState);
            Assert.IsFalse(childSet.Contains(child));

            parent.Children.Add(child);
            Assert.AreEqual(EntityState.Modified, child.EntityState);
            Assert.IsTrue(childSet.Contains(child));

            parent.Children.Remove(child);
            Assert.AreEqual(EntityState.Deleted, child.EntityState);
            Assert.IsFalse(childSet.Contains(child));

            // verify the same scenario for a singleton composition
            GrandChild gc = new GrandChild { ID = 1 };
            GreatGrandChild ggc = new GreatGrandChild { ID = 1, ParentID = 1 };
            container.LoadEntities(new Entity[] { gc, ggc });

            Assert.AreSame(ggc, gc.Child);

            gc.Child = null;
            Assert.AreEqual(EntityState.Deleted, ggc.EntityState);
            Assert.IsFalse(ggChildSet.Contains(ggc));

            gc.Child = ggc;
            Assert.AreEqual(EntityState.Unmodified, ggc.EntityState);
            Assert.IsTrue(ggChildSet.Contains(ggc));

            gc.Child = null;
            Assert.AreEqual(EntityState.Deleted, ggc.EntityState);
            Assert.IsFalse(ggChildSet.Contains(ggc));
        }
 public void CustomOp_GreatGrandChild(GreatGrandChild greatGrandChild)
 {
     this.SetOperationInvoked(greatGrandChild, "CustomOp_GreatGrandChild");
     ((CompositionEntityBase)greatGrandChild).OperationResult += ",CustomOp_GreatGrandChild";
 }
        public void Changeset_GetAssociatedChanges_Singleton()
        {
            DomainServiceDescription dsd = DomainServiceDescription.GetDescription(typeof(CompositionScenarios_Explicit));

            // verify singleton change of None
            GreatGrandChild unmodifiedGgc = new GreatGrandChild();
            GrandChild currGrandChild = new GrandChild
            {
                Child = unmodifiedGgc
            };
            GrandChild origGrandChild = new GrandChild
            {
                Child = unmodifiedGgc
            };
            ChangeSetEntry gcOperation = new ChangeSetEntry(1, currGrandChild, origGrandChild, DomainOperation.Update);
            gcOperation.Associations = new Dictionary<string, int[]> { { "Child", new int[] { 2 } } };
            ChangeSetEntry ggcOperation = new ChangeSetEntry(2, unmodifiedGgc, null, DomainOperation.None);
            ChangeSet cs = new ChangeSet(new ChangeSetEntry[] { gcOperation, ggcOperation });
            GreatGrandChild ggcChange = cs.GetAssociatedChanges(currGrandChild, p => p.Child, ChangeOperation.None).Cast<GreatGrandChild>().SingleOrDefault();
            Assert.AreSame(unmodifiedGgc, ggcChange);

            // verify singleton insert
            GreatGrandChild newGgc = new GreatGrandChild();
            currGrandChild = new GrandChild
            {
                Child = newGgc
            };
            origGrandChild = new GrandChild
            {
                Child = null
            };
            gcOperation = new ChangeSetEntry(1, currGrandChild, origGrandChild, DomainOperation.Update);
            gcOperation.Associations = new Dictionary<string, int[]> { { "Child", new int[] { 2 } } };
            ggcOperation = new ChangeSetEntry(2, newGgc, null, DomainOperation.Insert);
            cs = new ChangeSet(new ChangeSetEntry[] { gcOperation, ggcOperation });
            ggcChange = cs.GetAssociatedChanges(currGrandChild, p => p.Child, ChangeOperation.Insert).Cast<GreatGrandChild>().SingleOrDefault();
            Assert.AreSame(newGgc, ggcChange);
            Assert.AreEqual(ChangeOperation.Insert, cs.GetChangeOperation(newGgc));

            // verify singleton update
            GreatGrandChild modifiedGgc = new GreatGrandChild();
            currGrandChild = new GrandChild
            {
                Child = modifiedGgc
            };
            origGrandChild = new GrandChild
            {
                Child = modifiedGgc
            };
            gcOperation = new ChangeSetEntry(1, currGrandChild, origGrandChild, DomainOperation.Update);
            gcOperation.Associations = new Dictionary<string, int[]> { { "Child", new int[] { 2 } } };
            ggcOperation = new ChangeSetEntry(2, modifiedGgc, unmodifiedGgc, DomainOperation.Update);
            cs = new ChangeSet(new ChangeSetEntry[] { gcOperation, ggcOperation });
            ggcChange = cs.GetAssociatedChanges(currGrandChild, p => p.Child, ChangeOperation.Update).Cast<GreatGrandChild>().SingleOrDefault();
            Assert.AreSame(modifiedGgc, ggcChange);
            Assert.AreSame(unmodifiedGgc, cs.GetOriginal(modifiedGgc));
            Assert.AreEqual(ChangeOperation.Update, cs.GetChangeOperation(modifiedGgc));

            // verify singleton delete
            GreatGrandChild deletedGgc = new GreatGrandChild();
            currGrandChild = new GrandChild
            {
                Child = null
            };
            origGrandChild = new GrandChild
            {
                Child = deletedGgc
            };
            gcOperation = new ChangeSetEntry(1, currGrandChild, null, DomainOperation.Update);
            gcOperation.OriginalAssociations = new Dictionary<string, int[]>() { { "Child", new int[] { 2 } } };
            ggcOperation = new ChangeSetEntry(2, deletedGgc, null, DomainOperation.Delete);
            gcOperation.OriginalAssociations = new Dictionary<string, int[]>() { { "Child", new int[] { 2 } } };
            cs = new ChangeSet(new ChangeSetEntry[] { gcOperation, ggcOperation });
            ggcChange = cs.GetAssociatedChanges(currGrandChild, p => p.Child, ChangeOperation.Delete).Cast<GreatGrandChild>().SingleOrDefault();
            Assert.AreSame(deletedGgc, ggcChange);
            Assert.AreSame(null, cs.GetOriginal(deletedGgc));
            Assert.AreEqual(ChangeOperation.Delete, cs.GetChangeOperation(deletedGgc));
        }