[WorkItem(191649)] // related bug public void Composition_MoveChildToNewParent() { 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 p1 = new Parent() { ID = 1 }; Parent p2 = new Parent() { ID = 2 }; container.LoadEntities(new Entity[] { p1, new Child { ID = 1, ParentID = 1 }, new Child { ID = 2, ParentID = 1 }, p2, new Child { ID = 3, ParentID = 2 }, new Child { ID = 4, ParentID = 2 } }); Assert.AreEqual(2, p1.Children.Count()); Assert.AreEqual(2, p2.Children.Count()); Child child = p1.Children.ElementAt(0); p1.Children.Remove(child); Assert.AreEqual(1, p1.Children.Count()); Assert.AreEqual(2, p2.Children.Count()); // This is the repro - this addition was causing the counts to be 1 and 4 below p2.Children.Add(child); Assert.AreEqual(1, p1.Children.Count); Assert.AreEqual(3, p2.Children.Count); Assert.AreEqual(EntityState.Modified, child.EntityState); Assert.AreSame(p2, child.Parent); }
public void Entity_RemoveParent() { ConfigurableEntityContainer container = new ConfigurableEntityContainer(); container.CreateSet<Parent>(EntitySetOperations.All); container.CreateSet<Child>(EntitySetOperations.All); container.CreateSet<GrandChild>(EntitySetOperations.All); EntitySet<Parent> parentSet = container.GetEntitySet<Parent>(); EntitySet<Child> childSet = container.GetEntitySet<Child>(); Parent parent1 = new Parent() { ID = 1 }; Parent parent2 = new Parent() { ID = 2 }; Child child = new Child() { 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."); parentSet.Remove(parent1); EntityChangeSet changeSet = container.GetChanges(); Assert.AreEqual(2, changeSet.Count()); }
public void Entity_ChildCannotBeItsParent() { ConfigurableEntityContainer container = new ConfigurableEntityContainer(); container.CreateSet<SelfReferencingComposition>(EntitySetOperations.All); EntitySet<SelfReferencingComposition> childSet = container.GetEntitySet<SelfReferencingComposition>(); SelfReferencingComposition child = new SelfReferencingComposition() { ID = 1 }; childSet.Attach(child); // Verify that changing the parent throws an exception. ExceptionHelper.ExpectInvalidOperationException(delegate { child.Parent = child; }, Resource.Entity_ChildCannotBeItsParent); }
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_ParentUpdateOnDelete() { ConfigurableEntityContainer container = new ConfigurableEntityContainer(); container.CreateSet<Parent>(EntitySetOperations.All); container.CreateSet<Child>(EntitySetOperations.All); container.CreateSet<GrandChild>(EntitySetOperations.All); EntitySet<Parent> parentSet = container.GetEntitySet<Parent>(); EntitySet<Child> childSet = container.GetEntitySet<Child>(); Parent parent1 = new Parent() { ID = 1 }; Child child1 = new Child() { ID = 1, Parent = parent1 }; container.LoadEntities(new Entity[] { parent1, child1 }); // insert new parent and child Parent newParent = new Parent(); Child newChild = new Child(); newChild.Parent = newParent; parentSet.Add(newParent); // When the parent is removed, all it's children are also removed. // This causes the child ParentID to be set to 0, which means it now // matches the new Parent.Children collection. The removed child is added to // the new parent's collection, which causes child.Parent to be updated. // However that add is transitory - once the child is removed from the // entity set, it is removed from the new entity's child collection. // That invalid update will result in an exception on submit. parentSet.Remove(parent1); Assert.AreEqual(1, newParent.Children.Count); Assert.IsTrue(newParent.Children.Contains(newChild)); // if we allow the transitory phase, on accept changes we have to be // sure things are fixed up Assert.AreEqual(EntityState.Deleted, parent1.EntityState); Assert.AreEqual(EntityState.Deleted, child1.EntityState); Assert.AreSame(newParent, newChild.Parent); // changeset validation succeeds, since the parent is deleted along // with the child EntityChangeSet changeSet = container.GetChanges(); Assert.IsTrue(changeSet.AddedEntities.Count == 2 && changeSet.RemovedEntities.Count == 2); ChangeSetBuilder.CheckForInvalidUpdates(changeSet); }
public void Composition_EntityReferenceBug() { ConfigurableEntityContainer container = new ConfigurableEntityContainer(); container.CreateSet<SelfReferencingComposition_OneToMany>(EntitySetOperations.All); SelfReferencingComposition_OneToMany s1 = new SelfReferencingComposition_OneToMany() { ID = 1 }; SelfReferencingComposition_OneToMany s2 = new SelfReferencingComposition_OneToMany() { ID = 2, ParentID = 1 }; SelfReferencingComposition_OneToMany s3 = new SelfReferencingComposition_OneToMany() { ID = 3, ParentID = 1 }; SelfReferencingComposition_OneToMany s4 = new SelfReferencingComposition_OneToMany() { ID = 4, ParentID = 3 }; container.LoadEntities(new Entity[] { s1, s2, s3, s4 }); SelfReferencingComposition_OneToMany child = s1.Children.Single(p => p.ID == 2); child.Value += "x"; EntityChangeSet cs = container.GetChanges(); Assert.AreEqual(2, cs.ModifiedEntities.Count); List<ChangeSetEntry> entries = ChangeSetBuilder.Build(cs); Assert.AreEqual(4, entries.Count); }
[Ignore] // repro test - enable once bug is fixed public void CompositionSelfReference_UpdateChildBypassingParent() { ConfigurableEntityContainer container = new ConfigurableEntityContainer(); container.CreateSet<SelfReferencingComposition_OneToMany>(EntitySetOperations.All); SelfReferencingComposition_OneToMany s1 = new SelfReferencingComposition_OneToMany() { ID = 1 }; SelfReferencingComposition_OneToMany s2 = new SelfReferencingComposition_OneToMany() { ID = 2, ParentID = 1 }; container.LoadEntities(new Entity[] { s1, s2 }); // load the child w/o loading the parent SelfReferencingComposition_OneToMany child = container.GetEntitySet<SelfReferencingComposition_OneToMany>().Single(p => p.ID == 2); Assert.IsNull(((Entity)child).Parent); child.Value += "x"; // When this bug is fixed, we'd expect an exception during ChangeSetBuilder.Build EntityChangeSet cs = container.GetChanges(); List<ChangeSetEntry> entries = ChangeSetBuilder.Build(cs); }
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 Composition_AddChildPreviouslyReferencingOtherParent() { 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 p1 = new Parent() { ID = 1 }; Parent p2 = new Parent() { ID = 2 }; container.LoadEntities(new Entity[] { p1, p2 }); Child child = new Child() { ID = 1, ParentID = 2 }; p1.Children.Add(child); Assert.AreEqual(EntityState.Modified, p1.EntityState); Assert.IsTrue(childSet.HasChanges); }