public void VirtualEndPointQuery_OneMany_ObjectIncludedInTwoCollections()
        {
            SetDatabaseModifyable();

            var companyID = CreateCompanyAndSetIndustrialSectorInOtherTransaction(DomainObjectIDs.IndustrialSector1);
            var company   = companyID.GetObject <Company> ();

            var industrialSector1 = DomainObjectIDs.IndustrialSector1.GetObject <IndustrialSector> ();

            industrialSector1.Companies.EnsureDataComplete();

            SetIndustrialSectorInOtherTransaction(company.ID, DomainObjectIDs.IndustrialSector2);

            var industrialSector2 = DomainObjectIDs.IndustrialSector2.GetObject <IndustrialSector> ();

            industrialSector2.Companies.EnsureDataComplete();

            Assert.That(company.IndustrialSector, Is.SameAs(industrialSector1));
            Assert.That(industrialSector1.Companies, Has.Member(company));
            Assert.That(industrialSector2.Companies, Has.Member(company));

            CheckSyncState(company, c => c.IndustrialSector, true);
            CheckSyncState(industrialSector1, s => s.Companies, true);
            CheckSyncState(industrialSector2, s => s.Companies, false);

            BidirectionalRelationSyncService.Synchronize(TestableClientTransaction, RelationEndPointID.Resolve(industrialSector2, s => s.Companies));

            Assert.That(company.IndustrialSector, Is.SameAs(industrialSector1));
            Assert.That(industrialSector1.Companies, Has.Member(company));
            Assert.That(industrialSector2.Companies, Has.No.Member(company));

            CheckSyncState(company, c => c.IndustrialSector, true);
            CheckSyncState(industrialSector1, s => s.Companies, true);
            CheckSyncState(industrialSector2, s => s.Companies, true);
        }
        public void ObjectLoaded_WithInconsistentForeignKey_OneOne_Null()
        {
            Employee employee;
            Computer computer;

            using (ClientTransaction.Current.CreateSubTransaction().EnterDiscardingScope())
            {
                PrepareInconsistentState_InconsistentForeignKeyLoaded_VirtualSideAlreadyNull(out employee, out computer);

                Assert.That(computer.Employee, Is.SameAs(employee));
                Assert.That(employee.Computer, Is.Null);

                CheckSyncState(computer, c => c.Employee, false);
                CheckSyncState(employee, e => e.Computer, true);

                BidirectionalRelationSyncService.Synchronize(ClientTransaction.Current, RelationEndPointID.Resolve(computer, c => c.Employee));

                CheckSyncState(computer, c => c.Employee, true);
                CheckSyncState(employee, e => e.Computer, true);

                Assert.That(employee.Computer, Is.SameAs(computer));
                Assert.That(computer.Employee, Is.SameAs(employee));
            }

            CheckSyncState(computer, c => c.Employee, true);
            CheckSyncState(employee, e => e.Computer, true);

            Assert.That(employee.Computer, Is.SameAs(computer));
            Assert.That(computer.Employee, Is.SameAs(employee));
        }
예제 #3
0
        public void ObjectLoaded_WithInconsistentForeignKey_OneOne_Null()
        {
            Employee employee;
            Computer computer;

            PrepareInconsistentState_InconsistentForeignKeyLoaded_VirtualSideAlreadyNull(out employee, out computer);

            Assert.That(computer.Employee, Is.SameAs(employee));
            Assert.That(employee.Computer, Is.Null);

            CheckSyncState(computer, c => c.Employee, false);
            CheckSyncState(employee, e => e.Computer, true);

            // sync states not changed by Rollback
            CheckSyncState(computer, c => c.Employee, false);
            CheckSyncState(employee, e => e.Computer, true);

            CheckActionThrows <InvalidOperationException> (employee.Delete, "out of sync with the virtual property");
            CheckActionThrows <InvalidOperationException> (computer.Delete, "out of sync with the opposite property");
            CheckActionThrows <InvalidOperationException> (() => computer.Employee = null, "out of sync with the opposite property");
            CheckActionThrows <InvalidOperationException> (() => employee.Computer = computer, "out of sync with the virtual property");

            CheckActionWorks(() => employee.Computer = Computer.NewObject());
            ClientTransaction.Current.Rollback();

            BidirectionalRelationSyncService.Synchronize(ClientTransaction.Current, RelationEndPointID.Resolve(computer, c => c.Employee));

            CheckSyncState(computer, c => c.Employee, true);
            CheckSyncState(employee, e => e.Computer, true);

            Assert.That(employee.Computer, Is.SameAs(computer));
            Assert.That(computer.Employee, Is.SameAs(employee));
        }
        public void VirtualEndPointQuery_OneOne_ObjectReturned_ThatLocallyPointsToNull()
        {
            Computer computer;
            Employee employee;

            using (ClientTransaction.Current.CreateSubTransaction().EnterDiscardingScope())
            {
                PrepareInconsistentState_OneOne_ObjectReturned_ThatLocallyPointsToNull(out computer, out employee);

                Assert.That(employee.Computer, Is.SameAs(computer));
                Assert.That(computer.Employee, Is.Null);

                CheckSyncState(computer, c => c.Employee, true);
                CheckSyncState(employee, e => e.Computer, false);

                BidirectionalRelationSyncService.Synchronize(ClientTransaction.Current, RelationEndPointID.Resolve(employee, e => e.Computer));

                CheckSyncState(computer, c => c.Employee, true);
                CheckSyncState(employee, e => e.Computer, true);

                Assert.That(employee.Computer, Is.Null);
                Assert.That(computer.Employee, Is.Null);
            }

            CheckSyncState(computer, c => c.Employee, true);
            CheckSyncState(employee, e => e.Computer, true);

            Assert.That(employee.Computer, Is.Null);
            Assert.That(computer.Employee, Is.Null);
        }
        public void VirtualEndPointQuery_OneMany_Consistent_CollectionLoadedFirst()
        {
            Order     order1;
            OrderItem orderItem1;

            using (ClientTransaction.Current.CreateSubTransaction().EnterDiscardingScope())
            {
                order1 = DomainObjectIDs.Order1.GetObject <Order> ();
                order1.OrderItems.EnsureDataComplete();
                orderItem1 = DomainObjectIDs.OrderItem1.GetObject <OrderItem>();

                Assert.That(orderItem1.Order, Is.SameAs(order1));
                Assert.That(order1.OrderItems, Has.Member(orderItem1));

                CheckSyncState(orderItem1, oi => oi.Order, true);
                CheckSyncState(orderItem1.Order, o => o.OrderItems, true);

                Assert.That(order1.OrderItems, Has.Member(orderItem1));
                Assert.That(orderItem1.Order, Is.SameAs(order1));

                CheckSyncState(orderItem1, oi => oi.Order, true);
                CheckSyncState(orderItem1.Order, o => o.OrderItems, true);

                // these do nothing
                BidirectionalRelationSyncService.Synchronize(ClientTransaction.Current, RelationEndPointID.Resolve(orderItem1, oi => oi.Order));
                BidirectionalRelationSyncService.Synchronize(ClientTransaction.Current, RelationEndPointID.Resolve(orderItem1.Order, o => o.OrderItems));

                CheckSyncState(orderItem1, oi => oi.Order, true);
                CheckSyncState(orderItem1.Order, o => o.OrderItems, true);
            }

            CheckSyncState(orderItem1, oi => oi.Order, true);
            CheckSyncState(orderItem1.Order, o => o.OrderItems, true);
        }
        public void Synchronize_WithSubtransactions_LoadedInRootAndSub_SyncedInSub()
        {
            Company          company;
            IndustrialSector industrialSector;

            PrepareInconsistentState_OneMany_ObjectIncluded(out company, out industrialSector);

            CheckSyncState(company, c => c.IndustrialSector, true);
            CheckSyncState(industrialSector, s => s.Companies, false);

            using (ClientTransaction.Current.CreateSubTransaction().EnterDiscardingScope())
            {
                var relationEndPointID = RelationEndPointID.Resolve(industrialSector, s => s.Companies);

                var dataManager = ClientTransactionTestHelper.GetDataManager(ClientTransaction.Current);
                var endPoint    = dataManager.GetRelationEndPointWithLazyLoad(relationEndPointID);
                Assert.That(endPoint.IsSynchronized, Is.Null);

                endPoint.EnsureDataComplete();
                Assert.That(endPoint.IsSynchronized, Is.False);

                BidirectionalRelationSyncService.Synchronize(ClientTransaction.Current, relationEndPointID);

                CheckSyncState(industrialSector, s => s.Companies, true);
                Assert.That(endPoint.IsSynchronized, Is.True);
            }

            CheckSyncState(industrialSector, s => s.Companies, true);
        }
예제 #7
0
        public void Synchronize_InTransactionHierarchy_StartsWithRoot()
        {
            var endPointID = RelationEndPointID.Create(DomainObjectIDs.Order1, typeof(Order), "OrderItems");

            var endPointMockInParent = MockRepository.GenerateStrictMock <IRelationEndPoint> ();

            endPointMockInParent.Stub(stub => stub.ID).Return(endPointID);
            endPointMockInParent.Stub(stub => stub.Definition).Return(endPointID.Definition);
            endPointMockInParent.Stub(stub => stub.IsDataComplete).Return(true);
            endPointMockInParent.Expect(mock => mock.Synchronize());
            endPointMockInParent.Replay();
            RelationEndPointManagerTestHelper.AddEndPoint(_relationEndPointManager, endPointMockInParent);

            var subTransaction    = _transaction.CreateSubTransaction();
            var endPointMockInSub = MockRepository.GenerateStrictMock <IRelationEndPoint> ();

            endPointMockInSub.Stub(stub => stub.ID).Return(endPointID);
            endPointMockInSub.Stub(stub => stub.Definition).Return(endPointID.Definition);
            endPointMockInSub.Stub(stub => stub.IsDataComplete).Return(true);
            endPointMockInSub.Expect(mock => mock.Synchronize());
            endPointMockInSub.Replay();
            DataManagerTestHelper.AddEndPoint(ClientTransactionTestHelper.GetDataManager(subTransaction), endPointMockInSub);

            BidirectionalRelationSyncService.Synchronize(subTransaction, endPointID);

            endPointMockInParent.VerifyAllExpectations();
            endPointMockInSub.VerifyAllExpectations();
        }
예제 #8
0
        public void Synchronize_AnonymousEndPoint()
        {
            var locationClientEndPoint = RelationEndPointID.Create(DomainObjectIDs.Location1, typeof(Location), "Client");
            var endPointID             = RelationEndPointID.Create(DomainObjectIDs.Client1, locationClientEndPoint.Definition.GetOppositeEndPointDefinition());

            BidirectionalRelationSyncService.Synchronize(_transaction, endPointID);
        }
        public void VirtualEndPointQuery_OneOne_Consistent_VirtualEndPointLoadedFirst()
        {
            Order       order1;
            OrderTicket orderTicket1;

            using (ClientTransaction.Current.CreateSubTransaction().EnterDiscardingScope())
            {
                order1 = DomainObjectIDs.Order1.GetObject <Order> ();
                order1.OrderTicket.EnsureDataAvailable();
                orderTicket1 = DomainObjectIDs.OrderTicket1.GetObject <OrderTicket> ();

                Assert.That(orderTicket1.Order, Is.SameAs(order1));
                Assert.That(order1.OrderTicket, Is.SameAs(orderTicket1));

                CheckSyncState(orderTicket1, oi => oi.Order, true);
                CheckSyncState(orderTicket1.Order, o => o.OrderTicket, true);

                Assert.That(order1.OrderTicket, Is.SameAs(orderTicket1));
                Assert.That(orderTicket1.Order, Is.SameAs(order1));

                CheckSyncState(orderTicket1, oi => oi.Order, true);
                CheckSyncState(orderTicket1.Order, o => o.OrderTicket, true);

                // these do nothing
                BidirectionalRelationSyncService.Synchronize(ClientTransaction.Current, RelationEndPointID.Resolve(orderTicket1, oi => oi.Order));
                BidirectionalRelationSyncService.Synchronize(ClientTransaction.Current, RelationEndPointID.Resolve(orderTicket1.Order, o => o.OrderTicket));

                CheckSyncState(orderTicket1, oi => oi.Order, true);
                CheckSyncState(orderTicket1.Order, o => o.OrderTicket, true);
            }

            CheckSyncState(orderTicket1, oi => oi.Order, true);
            CheckSyncState(orderTicket1.Order, o => o.OrderTicket, true);
        }
        public void Synchronize_WithSubtransactions_LoadedInRootAndSub_SyncedInRoot()
        {
            Computer computer;
            Employee employee;
            Employee employee2;

            PrepareInconsistentState_OneOne_ObjectReturned_ThatLocallyPointsSomewhereElse(out computer, out employee, out employee2);

            Assert.That(computer.Employee, Is.SameAs(employee2));
            Assert.That(employee.Computer, Is.SameAs(computer));
            Assert.That(employee2.Computer, Is.SameAs(computer));

            CheckSyncState(computer, c => c.Employee, true);
            CheckSyncState(employee, e => e.Computer, false);
            CheckSyncState(employee2, e => e.Computer, true);

            using (ClientTransaction.Current.CreateSubTransaction().EnterDiscardingScope())
            {
                TestableClientTransaction.EnsureDataComplete(RelationEndPointID.Resolve(computer, c => c.Employee));
                TestableClientTransaction.EnsureDataComplete(RelationEndPointID.Resolve(employee, e => e.Computer));
                TestableClientTransaction.EnsureDataComplete(RelationEndPointID.Resolve(employee2, e => e.Computer));

                BidirectionalRelationSyncService.Synchronize(ClientTransaction.Current.ParentTransaction, RelationEndPointID.Resolve(employee, e => e.Computer));

                CheckSyncState(computer, c => c.Employee, true);
                CheckSyncState(employee, e => e.Computer, true);
                CheckSyncState(employee2, e => e.Computer, true);
            }

            CheckSyncState(computer, c => c.Employee, true);
            CheckSyncState(employee, e => e.Computer, true);
            CheckSyncState(employee2, e => e.Computer, true);
        }
        public void ObjectLoaded_WithInconsistentForeignKey_OneOne_NonNull()
        {
            Employee employee;
            Computer computer;
            Computer computer2;

            using (ClientTransaction.Current.CreateSubTransaction().EnterDiscardingScope())
            {
                PrepareInconsistentState_InconsistentForeignKeyLoaded_VirtualSideAlreadyNonNull(out employee, out computer, out computer2);

                // computer.Employee and employee.Computer match, but computer2.Employee doesn't
                Assert.That(computer.Employee, Is.SameAs(employee));
                Assert.That(computer2.Employee, Is.SameAs(employee));
                Assert.That(employee.Computer, Is.SameAs(computer));

                CheckSyncState(computer, c => c.Employee, true);
                CheckSyncState(employee, e => e.Computer, true);
                CheckSyncState(computer2, c => c.Employee, false);

                CheckActionThrows <InvalidOperationException> (() =>
                                                               BidirectionalRelationSyncService.Synchronize(ClientTransaction.Current, RelationEndPointID.Resolve(computer2, c => c.Employee)),
                                                               "The object end-point '{0}/Remotion.Data.DomainObjects.UnitTests.TestDomain.Computer.Employee' "
                                                               + "cannot be synchronized with the virtual object end-point "
                                                               + "'{2}/Remotion.Data.DomainObjects.UnitTests.TestDomain.Employee.Computer' because "
                                                               + "the virtual relation property already refers to another object ('{1}'). To synchronize "
                                                               + "'{0}/Remotion.Data.DomainObjects.UnitTests.TestDomain.Computer.Employee', use "
                                                               + "UnloadService to unload either object '{1}' or the virtual object end-point "
                                                               + "'{2}/Remotion.Data.DomainObjects.UnitTests.TestDomain.Employee.Computer'.",
                                                               computer2.ID,
                                                               computer.ID,
                                                               employee.ID);

                // By unloading the employee.Computer -> computer relation, we can now synchronize computer2.Employee -> employee with employee.Computer
                UnloadService.UnloadVirtualEndPoint(ClientTransaction.Current, RelationEndPointID.Resolve(employee, e => e.Computer));

                BidirectionalRelationSyncService.Synchronize(ClientTransaction.Current, RelationEndPointID.Resolve(computer2, c => c.Employee));

                CheckSyncState(computer, c => c.Employee, false);
                CheckSyncState(computer2, c => c.Employee, true);
                CheckSyncState(employee, e => e.Computer, true);

                Assert.That(employee.Computer, Is.SameAs(computer2));
                Assert.That(computer2.Employee, Is.SameAs(employee));
                Assert.That(computer.Employee, Is.SameAs(employee));
            }

            CheckSyncState(computer, c => c.Employee, false);
            CheckSyncState(computer2, c => c.Employee, true);
            CheckSyncState(employee, e => e.Computer, true);

            Assert.That(employee.Computer, Is.SameAs(computer2));
            Assert.That(computer2.Employee, Is.SameAs(employee));
            Assert.That(computer.Employee, Is.SameAs(employee));
        }
        public void VirtualEndPointQuery_OneMany_ObjectIncluded_ThatLocallyPointsToSomewhereElse()
        {
            SetDatabaseModifyable();

            var company = CreateCompanyInDatabaseAndLoad();

            Assert.That(company.IndustrialSector, Is.Null);

            var industrialSector = DomainObjectIDs.IndustrialSector1.GetObject <IndustrialSector> (); // virtual end point not yet resolved

            SetIndustrialSectorInOtherTransaction(company.ID, industrialSector.ID);

            // Resolve virtual end point - the database says that company points to industrialSector, but the transaction says it points to null!
            var companiesOfIndustrialSector = industrialSector.Companies;

            companiesOfIndustrialSector.EnsureDataComplete();

            Assert.That(company.IndustrialSector, Is.Null);
            Assert.That(companiesOfIndustrialSector, Has.Member(company));

            CheckSyncState(company, c => c.IndustrialSector, true);
            CheckSyncState(industrialSector, s => s.Companies, false);

            var otherCompany = companiesOfIndustrialSector.FirstOrDefault(c => c != company);

            CheckSyncState(otherCompany, c => c.IndustrialSector, true);

            CheckActionWorks(company.Delete);
            TestableClientTransaction.Rollback(); // required so that the remaining actions can be tried below

            // sync states not changed by Rollback
            CheckSyncState(company, c => c.IndustrialSector, true);
            CheckSyncState(industrialSector, s => s.Companies, false);

            CheckActionWorks(() => industrialSector.Companies.Remove(otherCompany));
            CheckActionWorks(() => industrialSector.Companies.Add(Company.NewObject()));

            var companyIndex = industrialSector.Companies.IndexOf(company);

            CheckActionThrows <InvalidOperationException> (industrialSector.Delete, "out of sync with the opposite object property");
            CheckActionThrows <InvalidOperationException> (() => industrialSector.Companies.Remove(company), "out of sync with the opposite object property");
            CheckActionThrows <InvalidOperationException> (() => industrialSector.Companies[companyIndex] = Company.NewObject(), "out of sync with the opposite object property");
            CheckActionThrows <InvalidOperationException> (() => industrialSector.Companies = new ObjectList <Company> (), "out of sync with the opposite object property");
            CheckActionThrows <InvalidOperationException> (industrialSector.Delete, "out of sync with the opposite object property");

            CheckActionWorks(() => company.IndustrialSector = IndustrialSector.NewObject());

            BidirectionalRelationSyncService.Synchronize(ClientTransaction.Current, RelationEndPointID.Resolve(industrialSector, s => s.Companies));

            CheckSyncState(industrialSector, s => s.Companies, true);
            Assert.That(companiesOfIndustrialSector, Has.No.Member(company));

            CheckActionWorks(() => industrialSector.Companies.Add(company));
        }
예제 #13
0
        public void Synchronize_EndPointIncomplete()
        {
            var endPointID   = RelationEndPointID.Create(DomainObjectIDs.Order1, typeof(Order), "OrderItems");
            var endPointStub = MockRepository.GenerateStub <IRelationEndPoint> ();

            endPointStub.Stub(stub => stub.ID).Return(endPointID);
            endPointStub.Stub(stub => stub.Definition).Return(endPointID.Definition);
            endPointStub.Stub(stub => stub.IsDataComplete).Return(false);
            RelationEndPointManagerTestHelper.AddEndPoint(_relationEndPointManager, endPointStub);

            BidirectionalRelationSyncService.Synchronize(_transaction, endPointID);
        }
        public void VirtualEndPointQuery_OneMany_ObjectIncluded_ThatLocallyPointsToSomewhereElse()
        {
            Company          company;
            IndustrialSector industrialSector; // virtual end point not yet resolved

            using (ClientTransaction.Current.CreateSubTransaction().EnterDiscardingScope())
            {
                PrepareInconsistentState_OneMany_ObjectIncluded(out company, out industrialSector);

                CheckSyncState(company, c => c.IndustrialSector, true);
                CheckSyncState(industrialSector, s => s.Companies, false);

                var otherCompany = industrialSector.Companies.FirstOrDefault(c => c != company);
                CheckSyncState(otherCompany, c => c.IndustrialSector, true);

                CheckActionWorks(company.Delete);
                ClientTransaction.Current.Rollback(); // required so that the remaining actions can be tried below

                // sync states not changed by Rollback
                CheckSyncState(company, c => c.IndustrialSector, true);
                CheckSyncState(industrialSector, s => s.Companies, false);

                CheckActionWorks(() => industrialSector.Companies.Remove(otherCompany));
                CheckActionWorks(() => industrialSector.Companies.Add(Company.NewObject()));

                var companyIndex = industrialSector.Companies.IndexOf(company);
                CheckActionThrows <InvalidOperationException> (
                    () => industrialSector.Companies.Remove(company), "out of sync with the opposite object property");
                CheckActionThrows <InvalidOperationException> (
                    () => industrialSector.Companies[companyIndex] = Company.NewObject(), "out of sync with the opposite object property");
                CheckActionThrows <InvalidOperationException> (
                    () => industrialSector.Companies = new ObjectList <Company>(), "out of sync with the opposite object property");
                CheckActionThrows <InvalidOperationException> (industrialSector.Delete, "out of sync with the opposite object property");

                CheckActionWorks(() => company.IndustrialSector = IndustrialSector.NewObject());

                BidirectionalRelationSyncService.Synchronize(ClientTransaction.Current, RelationEndPointID.Resolve(industrialSector, s => s.Companies));

                CheckSyncState(industrialSector, s => s.Companies, true);
                Assert.That(industrialSector.Companies, Has.No.Member(company));

                CheckActionWorks(() => industrialSector.Companies.Add(company));
            }

            CheckSyncState(company, c => c.IndustrialSector, true);
            CheckSyncState(industrialSector, s => s.Companies, true);

            Assert.That(company.IndustrialSector, Is.Null);
            Assert.That(industrialSector.Companies, Has.No.Member(company));
        }
예제 #15
0
        public void VirtualEndPointQuery_OneOne_ObjectNotReturned_ThatLocallyPointsToHere()
        {
            Computer computer;
            Employee employee;
            Employee employee2;

            PrepareInconsistentState_OneOne_ObjectNotReturned_ThatLocallyPointsToHere(out computer, out employee, out employee2);

            Assert.That(computer.Employee, Is.SameAs(employee2));
            Assert.That(employee.Computer, Is.SameAs(computer));
            Assert.That(employee2.Computer, Is.Null);

            CheckSyncState(computer, c => c.Employee, false);
            CheckSyncState(employee, e => e.Computer, false);
            CheckSyncState(employee2, e => e.Computer, true);

            // sync states not changed by Rollback
            CheckSyncState(computer, c => c.Employee, false);
            CheckSyncState(employee, e => e.Computer, false);
            CheckSyncState(employee2, e => e.Computer, true);

            CheckActionThrows <InvalidOperationException> (computer.Delete, "out of sync with the opposite property");
            CheckActionThrows <InvalidOperationException> (employee.Delete, "out of sync with the opposite object property");
            CheckActionThrows <InvalidOperationException> (employee2.Delete, "out of sync with the virtual property");
            CheckActionThrows <InvalidOperationException> (() => employee.Computer = null, "out of sync with the opposite object property");
            CheckActionThrows <InvalidOperationException> (() => employee.Computer = Computer.NewObject(), "out of sync with the opposite object property");
            CheckActionThrows <InvalidOperationException> (() => computer.Employee = employee, "out of sync with the opposite property");
            CheckActionThrows <InvalidOperationException> (() => computer.Employee = null, "out of sync with the opposite property");

            BidirectionalRelationSyncService.Synchronize(ClientTransaction.Current, RelationEndPointID.Resolve(computer, c => c.Employee));

            CheckSyncState(computer, c => c.Employee, true);
            CheckSyncState(employee, e => e.Computer, false);
            CheckSyncState(employee2, e => e.Computer, true);

            Assert.That(computer.Employee, Is.SameAs(employee2));
            Assert.That(employee.Computer, Is.SameAs(computer));
            Assert.That(employee2.Computer, Is.SameAs(computer));

            BidirectionalRelationSyncService.Synchronize(ClientTransaction.Current, RelationEndPointID.Resolve(employee, e => e.Computer));

            CheckSyncState(computer, c => c.Employee, true);
            CheckSyncState(employee, e => e.Computer, true);
            CheckSyncState(employee2, e => e.Computer, true);

            Assert.That(computer.Employee, Is.SameAs(employee2));
            Assert.That(employee.Computer, Is.Null);
            Assert.That(employee2.Computer, Is.SameAs(computer));
        }
        public void Synchronize()
        {
            var orderCollection = _customer.Orders;

            _customer.Orders.EnsureDataComplete();

            _eventReceiverMock
            .Expect(mock => mock.OnReplaceData())
            .WhenCalled(mi => Assert.That(orderCollection, Is.EqualTo(new[] { _itemA, _itemB })));
            _eventReceiverMock.Replay();
            _customer.Orders.SetEventReceiver(_eventReceiverMock);

            BidirectionalRelationSyncService.Synchronize(TestableClientTransaction, _customer.Orders.AssociatedEndPointID);

            _eventReceiverMock.VerifyAllExpectations();
        }
예제 #17
0
        public void Synchronize()
        {
            var endPointID = RelationEndPointID.Create(DomainObjectIDs.Order1, typeof(Order), "OrderItems");

            var endPointMock = MockRepository.GenerateStrictMock <IRelationEndPoint>();

            endPointMock.Stub(stub => stub.ID).Return(endPointID);
            endPointMock.Stub(stub => stub.Definition).Return(endPointID.Definition);
            endPointMock.Stub(stub => stub.IsDataComplete).Return(true);
            endPointMock.Expect(mock => mock.Synchronize());
            endPointMock.Replay();
            RelationEndPointManagerTestHelper.AddEndPoint(_relationEndPointManager, endPointMock);

            BidirectionalRelationSyncService.Synchronize(_transaction, endPointID);

            endPointMock.VerifyAllExpectations();
        }
예제 #18
0
        public void VirtualEndPointQuery_OneOne_Consistent_RealEndPointLoadedFirst()
        {
            var orderTicket1 = DomainObjectIDs.OrderTicket1.GetObject <OrderTicket> ();
            var order1       = DomainObjectIDs.Order1.GetObject <Order> ();

            Assert.That(orderTicket1.Order, Is.SameAs(order1));
            Assert.That(order1.OrderTicket, Is.SameAs(orderTicket1));

            CheckSyncState(orderTicket1, oi => oi.Order, true);
            CheckSyncState(orderTicket1.Order, o => o.OrderTicket, true);

            // these do nothing
            BidirectionalRelationSyncService.Synchronize(ClientTransaction.Current, RelationEndPointID.Resolve(orderTicket1, oi => oi.Order));
            BidirectionalRelationSyncService.Synchronize(ClientTransaction.Current, RelationEndPointID.Resolve(orderTicket1.Order, o => o.OrderTicket));

            CheckSyncState(orderTicket1, oi => oi.Order, true);
            CheckSyncState(orderTicket1.Order, o => o.OrderTicket, true);
        }
        public void SynchronizeOppositeEndPoint()
        {
            // Prepare an item in unsynchronized state
            Order unsynchronizedOrder = PrepareUnsynchronizedOrder(DomainObjectIDs.Order4, _customer.ID);

            var orderCollection = _customer.Orders;

            orderCollection.EnsureDataComplete();

            _eventReceiverMock
            .Expect(mock => mock.OnReplaceData())
            .WhenCalled(mi => Assert.That(orderCollection, Is.EqualTo(new[] { _itemA, _itemB, unsynchronizedOrder })));
            _eventReceiverMock.Replay();
            _customer.Orders.SetEventReceiver(_eventReceiverMock);

            BidirectionalRelationSyncService.Synchronize(TestableClientTransaction, RelationEndPointID.Resolve(unsynchronizedOrder, o => o.Customer));

            _eventReceiverMock.VerifyAllExpectations();
        }
        public void VirtualEndPointQuery_OneMany_Consistent_CollectionLoadedFirst()
        {
            var order1 = DomainObjectIDs.Order1.GetObject <Order> ();

            order1.OrderItems.EnsureDataComplete();
            var orderItem1 = DomainObjectIDs.OrderItem1.GetObject <OrderItem>();

            Assert.That(orderItem1.Order, Is.SameAs(order1));
            Assert.That(order1.OrderItems, Has.Member(orderItem1));

            CheckSyncState(orderItem1, oi => oi.Order, true);
            CheckSyncState(orderItem1.Order, o => o.OrderItems, true);

            // these do nothing
            BidirectionalRelationSyncService.Synchronize(TestableClientTransaction, RelationEndPointID.Resolve(orderItem1, oi => oi.Order));
            BidirectionalRelationSyncService.Synchronize(TestableClientTransaction, RelationEndPointID.Resolve(orderItem1.Order, o => o.OrderItems));

            CheckSyncState(orderItem1, oi => oi.Order, true);
            CheckSyncState(orderItem1.Order, o => o.OrderItems, true);
        }
        public void ObjectLoaded_WithInconsistentForeignKey_OneMany()
        {
            SetDatabaseModifyable();

            // set up new IndustrialSector object in database with one company
            var industrialSector = CreateIndustrialSectorInDatabaseAndLoad();

            industrialSector.Companies.EnsureDataComplete();

            // in parallel transaction, add a second Company to the IndustrialSector
            var newCompanyID = CreateCompanyAndSetIndustrialSectorInOtherTransaction(industrialSector.ID);

            Assert.That(industrialSector.Companies.Count, Is.EqualTo(1));

            // load Company into this transaction; in the database, the Company has a foreign key to the IndustrialSector
            var newCompany = newCompanyID.GetObject <Company> ();

            Assert.That(newCompany.IndustrialSector, Is.SameAs(industrialSector));
            Assert.That(industrialSector.Companies, Has.No.Member(newCompany));
            Assert.That(industrialSector.Companies.Count, Is.EqualTo(1));

            CheckSyncState(industrialSector, s => s.Companies, true);
            CheckSyncState(newCompany, c => c.IndustrialSector, false);
            CheckSyncState(industrialSector.Companies[0], c => c.IndustrialSector, true);

            CheckActionThrows <InvalidOperationException> (newCompany.Delete, "out of sync with the opposite property");
            CheckActionThrows <InvalidOperationException> (industrialSector.Delete, "out of sync with the collection property");

            CheckActionWorks(() => industrialSector.Companies.RemoveAt(0));
            CheckActionWorks(() => industrialSector.Companies.Add(Company.NewObject()));

            CheckActionThrows <InvalidOperationException> (() => industrialSector.Companies.Add(newCompany), "out of sync with the collection property");
            CheckActionThrows <InvalidOperationException> (() => newCompany.IndustrialSector = null, "out of sync with the opposite property ");

            BidirectionalRelationSyncService.Synchronize(ClientTransaction.Current, RelationEndPointID.Resolve(newCompany, c => c.IndustrialSector));

            CheckSyncState(newCompany, c => c.IndustrialSector, true);
            Assert.That(industrialSector.Companies, Has.Member(newCompany));
            CheckActionWorks(() => newCompany.IndustrialSector = null);
            CheckActionWorks(() => industrialSector.Companies.Add(newCompany));
        }
        public void VirtualEndPointQuery_OneMany_ObjectNotIncluded_ThatLocallyPointsToHere()
        {
            SetDatabaseModifyable();

            var companyID = CreateCompanyAndSetIndustrialSectorInOtherTransaction(DomainObjectIDs.IndustrialSector1);
            var company   = companyID.GetObject <Company> ();

            Assert.That(company.Properties[typeof(Company), "IndustrialSector"].GetRelatedObjectID(), Is.EqualTo(DomainObjectIDs.IndustrialSector1));

            SetIndustrialSectorInOtherTransaction(company.ID, DomainObjectIDs.IndustrialSector2);

            var industrialSector = DomainObjectIDs.IndustrialSector1.GetObject <IndustrialSector> ();

            // Resolve virtual end point - the database says that company does not point to IndustrialSector1, but the transaction says it does!
            industrialSector.Companies.EnsureDataComplete();

            Assert.That(company.IndustrialSector, Is.SameAs(industrialSector));
            Assert.That(industrialSector.Companies, Has.No.Member(company));

            CheckSyncState(company, c => c.IndustrialSector, false);
            CheckSyncState(industrialSector, s => s.Companies, true);
            CheckSyncState(industrialSector.Companies[0], c => c.IndustrialSector, true);

            CheckActionThrows <InvalidOperationException> (company.Delete, "out of sync with the opposite property");
            CheckActionThrows <InvalidOperationException> (industrialSector.Delete, "out of sync with the collection property");

            CheckActionWorks(() => industrialSector.Companies.RemoveAt(0));
            CheckActionWorks(() => industrialSector.Companies.Add(Company.NewObject()));

            CheckActionThrows <InvalidOperationException> (() => industrialSector.Companies.Add(company), "out of sync with the collection property");
            CheckActionThrows <InvalidOperationException> (() => company.IndustrialSector = null, "out of sync with the opposite property ");

            BidirectionalRelationSyncService.Synchronize(ClientTransaction.Current, RelationEndPointID.Resolve(company, c => c.IndustrialSector));

            CheckSyncState(company, c => c.IndustrialSector, true);
            Assert.That(industrialSector.Companies, Has.Member(company));
            CheckActionWorks(() => company.IndustrialSector = null);
            CheckActionWorks(() => industrialSector.Companies.Add(company));
        }
        public void VirtualEndPointQuery_OneMany_ObjectNotIncluded_ThatLocallyPointsToHere()
        {
            Company          company;
            IndustrialSector industrialSector;

            using (ClientTransaction.Current.CreateSubTransaction().EnterDiscardingScope())
            {
                PrepareInconsistentState_OneMany_ObjectNotIncluded(out company, out industrialSector);

                Assert.That(company.IndustrialSector, Is.SameAs(industrialSector));
                Assert.That(industrialSector.Companies, Has.No.Member(company));

                CheckSyncState(company, c => c.IndustrialSector, false);
                CheckSyncState(industrialSector, s => s.Companies, true);
                CheckSyncState(industrialSector.Companies[0], c => c.IndustrialSector, true);

                CheckActionThrows <InvalidOperationException> (company.Delete, "out of sync with the opposite property");
                CheckActionThrows <InvalidOperationException> (industrialSector.Delete, "out of sync with the collection property");

                CheckActionWorks(() => industrialSector.Companies.RemoveAt(0));
                CheckActionWorks(() => industrialSector.Companies.Add(Company.NewObject()));

                CheckActionThrows <InvalidOperationException> (() => industrialSector.Companies.Add(company), "out of sync with the collection property");
                CheckActionThrows <InvalidOperationException> (() => company.IndustrialSector = null, "out of sync with the opposite property ");

                BidirectionalRelationSyncService.Synchronize(ClientTransaction.Current, RelationEndPointID.Resolve(company, c => c.IndustrialSector));

                CheckSyncState(company, c => c.IndustrialSector, true);
                Assert.That(industrialSector.Companies, Has.Member(company));
                CheckActionWorks(() => company.IndustrialSector = null);
                CheckActionWorks(() => industrialSector.Companies.Add(company));
            }

            CheckSyncState(company, c => c.IndustrialSector, true);
            CheckSyncState(industrialSector, s => s.Companies, true);

            Assert.That(company.IndustrialSector, Is.SameAs(industrialSector));
            Assert.That(industrialSector.Companies, Has.Member(company));
        }
예제 #24
0
        public void VirtualEndPointQuery_OneOne_ObjectNotReturned_ThatLocallyPointsToHere_WithChangedRelation()
        {
            SetDatabaseModifyable();

            var employee2 = DomainObjectIDs.Employee2.GetObject <Employee> ();

            var computer = CreateComputerAndSetEmployeeInOtherTransaction(employee2.ID).GetObject <Computer> ();

            Assert.That(computer.Employee, Is.SameAs(employee2));

            // 1:1 relations automatically cause virtual end-points to be marked loaded when the foreign key object is loaded, so unload the virtual side
            UnloadService.UnloadVirtualEndPoint(ClientTransaction.Current, RelationEndPointID.Resolve(employee2, e => e.Computer));

            SetEmployeeInOtherTransaction(computer.ID, DomainObjectIDs.Employee1);

            // Resolve virtual end point - the database says that computer points to employee1, but the transaction says computer points to employee2!
            Dev.Null = employee2.Computer;

            Assert.That(computer.Employee, Is.SameAs(employee2));
            Assert.That(employee2.Computer, Is.Null);

            CheckSyncState(computer, c => c.Employee, false);
            CheckSyncState(employee2, e => e.Computer, true);

            var newComputer = Computer.NewObject();

            employee2.Computer = newComputer;

            BidirectionalRelationSyncService.Synchronize(ClientTransaction.Current, RelationEndPointID.Resolve(computer, c => c.Employee));

            CheckSyncState(computer, c => c.Employee, true);
            CheckSyncState(employee2, e => e.Computer, true);

            Assert.That(computer.Employee, Is.SameAs(employee2));
            Assert.That(employee2.Computer, Is.SameAs(newComputer));
            Assert.That(employee2.Properties[typeof(Employee), "Computer"].GetOriginalValue <Computer>(), Is.SameAs(computer));
            Assert.That(employee2.State, Is.EqualTo(StateType.Changed));
        }
예제 #25
0
        public void Synchronize_EndPointNotRegistered()
        {
            var endPointID = RelationEndPointID.Create(DomainObjectIDs.OrderItem1, typeof(OrderItem), "Order");

            BidirectionalRelationSyncService.Synchronize(_transaction, endPointID);
        }
예제 #26
0
        public void Synchronize_UnidirectionalEndpoint()
        {
            var endPointID = RelationEndPointID.Create(DomainObjectIDs.Location1, typeof(Location), "Client");

            BidirectionalRelationSyncService.Synchronize(_transaction, endPointID);
        }
예제 #27
0
        public void ObjectLoaded_WithInconsistentForeignKey_OneOne_NonNull()
        {
            Employee employee;
            Computer computer;
            Computer computer2;

            PrepareInconsistentState_InconsistentForeignKeyLoaded_VirtualSideAlreadyNonNull(out employee, out computer, out computer2);

            // computer.Employee and employee.Computer match, but computer2.Employee doesn't
            Assert.That(computer.Employee, Is.SameAs(employee));
            Assert.That(computer2.Employee, Is.SameAs(employee));
            Assert.That(employee.Computer, Is.SameAs(computer));

            CheckSyncState(computer, c => c.Employee, true);
            CheckSyncState(employee, e => e.Computer, true);
            CheckSyncState(computer2, c => c.Employee, false);

            CheckActionWorks(computer.Delete);
            ClientTransaction.Current.Rollback();

            // sync states not changed by Rollback
            CheckSyncState(computer, c => c.Employee, true);
            CheckSyncState(employee, e => e.Computer, true);
            CheckSyncState(computer2, c => c.Employee, false);

            CheckActionThrows <InvalidOperationException> (employee.Delete, "out of sync with the virtual property");
            CheckActionThrows <InvalidOperationException> (computer2.Delete, "out of sync with the opposite property");
            CheckActionThrows <InvalidOperationException> (() => computer2.Employee = null, "out of sync with the opposite property");
            CheckActionThrows <InvalidOperationException> (() => employee.Computer  = computer2, "out of sync with the virtual property");

            CheckActionWorks(() => computer.Employee = null);
            ClientTransaction.Current.Rollback();

            CheckActionWorks(() => employee.Computer = null);
            ClientTransaction.Current.Rollback();

            CheckActionThrows <InvalidOperationException> (() =>
                                                           BidirectionalRelationSyncService.Synchronize(ClientTransaction.Current, RelationEndPointID.Resolve(computer2, c => c.Employee)),
                                                           "The object end-point '{0}/Remotion.Data.DomainObjects.UnitTests.TestDomain.Computer.Employee' "
                                                           + "cannot be synchronized with the virtual object end-point "
                                                           + "'{2}/Remotion.Data.DomainObjects.UnitTests.TestDomain.Employee.Computer' because "
                                                           + "the virtual relation property already refers to another object ('{1}'). To synchronize "
                                                           + "'{0}/Remotion.Data.DomainObjects.UnitTests.TestDomain.Computer.Employee', use "
                                                           + "UnloadService to unload either object '{1}' or the virtual object end-point "
                                                           + "'{2}/Remotion.Data.DomainObjects.UnitTests.TestDomain.Employee.Computer'.",
                                                           computer2.ID,
                                                           computer.ID,
                                                           employee.ID);

            // By unloading computer, we can notw synchronize the relation
            UnloadService.UnloadData(ClientTransaction.Current, computer.ID);
            BidirectionalRelationSyncService.Synchronize(ClientTransaction.Current, RelationEndPointID.Resolve(computer2, c => c.Employee));

            ClientTransaction.Current.EnsureDataAvailable(computer.ID);

            CheckSyncState(computer, c => c.Employee, true);
            CheckSyncState(computer2, c => c.Employee, true);
            CheckSyncState(employee, e => e.Computer, true);

            Assert.That(computer.Employee, Is.Null);
            Assert.That(employee.Computer, Is.SameAs(computer2));
            Assert.That(computer2.Employee, Is.SameAs(employee));
        }