/// <summary> /// Causes a comit operation on the <see cref="UnitOfWorkScopeTransaction"/> instance. /// </summary> /// <param name="scope">The <see cref="UnitOfWorkScope"/> instance that is calling the commit.</param> /// <remarks> /// This method can only by called by the scope currently on top of the stack. If Called by another scope then an /// <see cref="InvalidOperationException"/> is called. If the calling scope is last in the attached scope hierarchy, /// then a commit is called on the underling unit of work instance. /// </remarks> public void Commit(UnitOfWorkScope scope) { Guard.Against <ObjectDisposedException>(_disposed, "Transaction has been disposed. Cannot commit a disposed transaction."); Guard.Against <InvalidOperationException>(_transactionRolledback, "Cannot call commit on a rolledback transaction. A child scope or current scope has already rolled back the transaction. Call Rollback()"); Guard.Against <ArgumentNullException>(scope == null, "Cannot commit the transaction for a null UnitOfWorkScope instance."); Guard.Against <InvalidOperationException>(_attachedScopes.Peek() != scope, "Commit can only be called by the current UnitOfWorkScope instance. The UnitOfWorkScope provided does not match the current scope on the stack."); var currentScope = _attachedScopes.Pop(); if (_attachedScopes.Count != 0) { return; } //The calling UnitOfWorkScope is the root of the transaction. try { _unitOfWork.Flush(); _runningTransaction.Commit(); _runningTransaction.Dispose(); _unitOfWork.Dispose(); CurrentTransactions.Remove(this); } catch { _attachedScopes.Push(currentScope); throw; } }
// ------------------------------------------------------------------------------------- // Methods // ------------------------------------------------------------------------------------- public FacadeResult CancelAccount(long id) { #if DEBUG using (MiniProfiler.Current.Step("AccountFacade.CancelAccount")) { #endif using (var context = new UnitOfWorkScope(TransactionMode.New)) { var account = Account.GetById(id); var validationResults = new AccountValidator() .Validate(account); if (validationResults.IsValid == true) { account.IsActive = false; User.GetAllByAccountId(id).ForEach(user => { user.IsActive = false; UserCacheManager.Put(user); }); context.Commit(); AccountCacheManager.Put(account); return new FacadeResult(); } var error = validationResults.Errors .First().ErrorMessage .GetError(); return new FacadeResult(error); #if DEBUG } #endif } }
/// <summary> /// Gets a <see cref="UnitOfWorkScopeTransaction"/> instance that can be used by a <see cref="UnitOfWorkScope"/> instance. /// </summary> /// <param name="scope">The <see cref="UnitOfWorkScope"/> instance that is requesting the transaction.</param> /// <param name="isolationLevel">One of the values of <see cref="IsolationLevel"/> that specifies the transaction isolation level.</param> /// <param name="options">One of the values of <see cref="UnitOfWorkScopeTransactionOptions"/> that specifies options for using existing /// transacitons or creating new ones.</param> /// <returns>A <see cref="UnitOfWorkScopeTransaction"/> instance.</returns> public static UnitOfWorkScopeTransaction GetTransactionForScope(UnitOfWorkScope scope, IsolationLevel isolationLevel, UnitOfWorkScopeTransactionOptions options) { var useCompatibleTx = (options & UnitOfWorkScopeTransactionOptions.UseCompatible) == UnitOfWorkScopeTransactionOptions.UseCompatible; var createNewTx = (options & UnitOfWorkScopeTransactionOptions.CreateNew) == UnitOfWorkScopeTransactionOptions.CreateNew; Guard.Against <InvalidOperationException>(useCompatibleTx && createNewTx, "Cannot start a transaction with both UseCompatible and CreateNew specified " + "as a UnitOfWorkScopeTransactionOptions"); if (options == UnitOfWorkScopeTransactionOptions.UseCompatible) { var transaction = (from t in CurrentTransactions where t.IsolationLevel == isolationLevel select t).FirstOrDefault(); if (transaction != null) { transaction.AttachScope(scope); return(transaction); } } var factory = ServiceLocator.Current.GetInstance <IUnitOfWorkFactory>(); var newTransaction = new UnitOfWorkScopeTransaction(factory, isolationLevel); newTransaction.AttachScope(scope); CurrentTransactions.AddFirst(newTransaction); return(newTransaction); }
public void Calling_Commit_On_Parent_Scope_After_Child_Commit_Calls_Flush_On_UOW_And_Commit_On_Transaction() { var mockLocator = MockRepository.GenerateStub<IServiceLocator>(); var mockUOWFactory = MockRepository.GenerateMock<IUnitOfWorkFactory>(); var mockUOW = MockRepository.GenerateMock<IUnitOfWork>(); var mockTransaction = MockRepository.GenerateMock<ITransaction>(); mockLocator.Stub(x => x.GetInstance<IUnitOfWorkFactory>()).Return(mockUOWFactory).Repeat.Once(); mockUOWFactory.Expect(x => x.Create()).Return(mockUOW).Repeat.Once(); mockUOW.Expect(x => x.BeginTransaction(IsolationLevel.ReadCommitted)).IgnoreArguments().Return(mockTransaction).Repeat.Once(); mockUOW.Expect(x => x.Flush()).Repeat.Once(); mockTransaction.Expect(x => x.Commit()).Repeat.Once(); mockTransaction.Expect(x => x.Rollback()).Repeat.Never(); ServiceLocator.SetLocatorProvider(() => mockLocator); using (var parentScope = new UnitOfWorkScope(IsolationLevel.ReadCommitted)) { Assert.That(UnitOfWorkScope.HasStarted); using (var childScope = new UnitOfWorkScope(IsolationLevel.ReadCommitted)) { childScope.Commit(); } parentScope.Commit(); } Assert.That(!UnitOfWorkScope.HasStarted); mockUOWFactory.VerifyAllExpectations(); mockUOW.VerifyAllExpectations(); mockTransaction.VerifyAllExpectations(); }
/// <summary> /// Registers a scope as the top level scope on the <see cref="RunningScopes"/> stack. /// </summary> /// <param name="scope">The <see cref="UnitOfWorkScope"/> instance to set as the top level scope on the stack.</param> private static void RegisterScope(UnitOfWorkScope scope) { Guard.Against <ArgumentNullException>(scope == null, "Cannot register a null UnitOfWorkScope instance as the top level scope."); Data.UnitOfWork.Current = scope.UnitOfWork; //Setting the UnitOfWork isntance held by the scope as the current scope. RunningScopes.Push(scope); }
/// <summary> /// Attaches a <see cref="UnitOfWorkScope"/> instance to the <see cref="UnitOfWorkScopeTransaction"/> instance. /// </summary> /// <param name="scope"></param> void AttachScope(UnitOfWorkScope scope) { Guard.Against <ObjectDisposedException>(_disposed, "Transaction has been disposed. Cannot attach a scope to a disposed transaction."); Guard.Against <ArgumentNullException>(scope == null, "Cannot attach a null UnitOfWorkScope instance to the UnitOfWorkScopeTransaction instance."); _attachedScopes.Push(scope); //Push the scope on to the top of the stack. }
public void Should_not_auto_commit_when_scope_is_disposed() { var scopeId = Guid.Empty; using (var scope = new UnitOfWorkScope()) { scopeId = scope.ScopeId; //Simulating a rollback by not calling scope.Commit() } Assert.That(_transactionManager.CommitCount(scopeId), Is.EqualTo(0)); Assert.That(_transactionManager.RollbackCount(scopeId), Is.EqualTo(1)); }
public void Should_raise_commit_signal_when_commit_called() { var scopeId = Guid.Empty; _transactionManager.ScopeCommitAction = committingScope => committingScope.Complete(); using (var scope = new UnitOfWorkScope()) { scopeId = scope.ScopeId; scope.Commit(); } Assert.That(_transactionManager.CommitCount(scopeId), Is.EqualTo(1)); Assert.That(_transactionManager.RollbackCount(scopeId), Is.EqualTo(0)); }
public void Should_raise_rollback_signal_if_commit_failed() { var scopeId = Guid.Empty; _transactionManager.ScopeCommitAction = comittingScope => { throw new InvalidOperationException(); }; using (var scope = new UnitOfWorkScope()) { scopeId = scope.ScopeId; Assert.Throws<InvalidOperationException>(scope.Commit); } Assert.That(_transactionManager.CommitCount(scopeId), Is.EqualTo(1)); Assert.That(_transactionManager.RollbackCount(scopeId), Is.EqualTo(1)); }
public void Delete_Deletes_Record() { //Adding a dummy record. var newAddress = new Address { StreetAddress1 = "This record was inserted for deletion", City = "Fictional city", State = "LA", ZipCode = "12345" }; var newCustomer = new Customer { FirstName = ("John_DELETE_ME_" + DateTime.Now), LastName = ("Doe_DELETE_ME_" + DateTime.Now), Address = newAddress }; //Re-usable query to query for the matching record. var queryForCustomer = new Func<Db4oRepository<Customer>, Customer> (x => (from cust in x where cust.FirstName == newCustomer.FirstName && cust.LastName == newCustomer.LastName select cust).FirstOrDefault() ); using (var scope = new UnitOfWorkScope()) { var customerRepository = new Db4oRepository<Customer>(); var recordCheckResult = queryForCustomer(customerRepository); Assert.That(recordCheckResult, Is.Null); customerRepository.Add(newCustomer); scope.Commit(); } //Retrieve the record for deletion. using (var scope = new UnitOfWorkScope()) { var customerRepository = new Db4oRepository<Customer>(); var customerToDelete = queryForCustomer(customerRepository); Assert.That(customerToDelete, Is.Not.Null); customerRepository.Delete(customerToDelete); scope.Commit(); } //Ensure customer record is deleted. using (new UnitOfWorkScope()) { var customerRepository = new Db4oRepository<Customer>(); var recordCheckResult = queryForCustomer(customerRepository); Assert.That(recordCheckResult, Is.Null); } }
/// <summary> /// UnRegisters a <see cref="UnitOfWorkScope"/> as the top level scope on the stack. /// </summary> /// <param name="scope"></param> private static void UnRegisterScope(UnitOfWorkScope scope) { Guard.Against <ArgumentNullException>(scope == null, "Cannot Un-Register a null UnitOfWorkScope instance as the top level scope."); Guard.Against <InvalidOperationException>(RunningScopes.Peek() != scope, "The UnitOfWorkScope provided does not match the current top level scope. Cannot un-register the specified scope."); RunningScopes.Pop(); if (RunningScopes.Count > 0) { //If the Stack has additional scopes, set the current unit of work to the UnitOfWork instance held by the top most scope. UnitOfWorkScope currentScope = RunningScopes.Peek(); Data.UnitOfWork.Current = currentScope.UnitOfWork; } else { Data.UnitOfWork.Current = null; } }
public void Can_lazyload() { Customer customer = null; var testData = new EFTestData(Context); testData.Batch(x => { customer = x.CreateCustomer(); x.CreateOrderForCustomer(customer); }); using (var scope = new UnitOfWorkScope()) { var savedCustomer = new EFRepository<Customer>() .First(x => x.CustomerID == customer.CustomerID); Assert.That(savedCustomer, Is.Not.Null); Assert.That(savedCustomer.Orders.Count, Is.EqualTo(1)); scope.Commit(); } }
public void Can_delete() { Customer customer = null; var testData = new EFTestData(Context); testData.Batch(x => customer = x.CreateCustomer()); using (var scope = new UnitOfWorkScope()) { var repository = new EFRepository<Customer>(); var savedCustomer = repository.First(x => x.CustomerID == customer.CustomerID); repository.Delete(savedCustomer); scope.Commit(); } using (var scope = new UnitOfWorkScope()) { var repository = new EFRepository<Customer>(); Assert.That(repository.FirstOrDefault(x => x.CustomerID == customer.CustomerID), Is.Null); scope.Commit(); } }
public void Can_attach_modified_entity() { Customer customer = null; var testData = new EFTestData(Context); testData.Batch(x => customer = x.CreateCustomer()); Context.Detach(customer); Context.Dispose(); using (var scope = new UnitOfWorkScope()) { customer.LastName = "Changed"; var repository = new EFRepository<Customer>(); repository.Attach(customer); scope.Commit(); } Context = new PocoContext(ConnectionString); testData = new EFTestData(Context); customer = testData.Get<Customer>(x => x.CustomerID == customer.CustomerID); Assert.That(customer.LastName, Is.EqualTo("Changed")); }
public Account GetAccountById(long id) { #if DEBUG using (MiniProfiler.Current.Step("AccountFacade.GetAccountById")) { #endif var account = AccountCacheManager.Get(id); if (account == null) { using (var context = new UnitOfWorkScope(TransactionMode.Supress)) { account = Account.GetById(id); if (account != null) { AccountCacheManager.Put(account); } } } return account; #if DEBUG } #endif }
public void Can_attach() { Customer customer = null; var testData = new EFTestData(Context); testData.Batch(x => customer = x.CreateCustomer()); Context.Detach(customer); Context.Dispose(); using (var scope = new UnitOfWorkScope()) { var repository = new EFRepository<Customer>(); repository.Attach(customer); customer.FirstName = "Changed"; scope.Commit(); } Context = new CodeOnlyContext("SandboxCodeOnly").Context; testData = new EFTestData(Context); customer = testData.Get<Customer>(x => x.CustomerID == customer.CustomerID); Assert.That(customer.FirstName, Is.EqualTo("Changed")); }
/// <summary> /// Causes a Rollback operation on the <see cref="UnitOfWorkScopeTransaction"/> instance. /// </summary> /// <param name="scope">The <see cref="UnitOfWorkScope"/> instance that is calling the commit.</param> /// <remarks> /// This method can only be called by the scope currently on top of the stack. If called by another scope than the /// current <see cref="UnitOfWorkScope"/> instance, then a <see cref="InvalidOperationException"/> is thrown. If the /// calling scope is the last in the attached scope hierarchy, then a rollback is called on the underlying UnitOfWork /// instance. /// </remarks> public void Rollback(UnitOfWorkScope scope) { Guard.Against <ObjectDisposedException>(_disposed, "Transaction has been disposed. Cannot rollback a disposed transaction."); Guard.Against <ArgumentNullException>(scope == null, "Cannot rollback the transaction for a null UnitOfWork instance."); Guard.Against <InvalidOperationException>(_attachedScopes.Peek() != scope, "Rollback can only be called by the current UnitOfWorkScope instance. The UnitOfWorkScope provided does not match the current scope on the stack."); _transactionRolledback = true; _attachedScopes.Pop(); if (_attachedScopes.Count != 0) { return; } //The calling UnitOfWorkScope is the root of the transaction. _runningTransaction.Rollback(); _runningTransaction.Dispose(); _unitOfWork.Dispose(); CurrentTransactions.Remove(this); }
public FacadeResult<User> SignIn(string email, string password) { #if DEBUG using (MiniProfiler.Current.Step("AccountFacade.SignIn")) { #endif using (var context = new UnitOfWorkScope(TransactionMode.Supress)) { var user = User.GetActiveByEmail(email); if (user != null && user.IsPassword(password)) { UserCacheManager.Put(user); return new FacadeResult<User>(user); } var error = new FacadeError(20010, "WithPassword", "The supplied email and/or password are invalid."); return new FacadeResult<User>(error); } #if DEBUG } #endif }
public FacadeResult<User> SignUp(string name, string email, string password) { #if DEBUG using (MiniProfiler.Current.Step("AccountFacade.SignUp")) { #endif using (var context = new UnitOfWorkScope(TransactionMode.New)) { var user = User.Create(email, name, password); var userValidation = new UserValidator() .Validate(user); if (userValidation.IsValid == false) { var error = userValidation.Errors .First().ErrorMessage .GetError(); return new FacadeResult<User>(error); } context.Commit(); UserCacheManager.Put(user); return new FacadeResult<User>(user); } #if DEBUG } #endif }
public FacadeResult<User> UpdateUserPassword(long userId, string password) { #if DEBUG using (MiniProfiler.Current.Step("AccountFacade.UpdateUserPassword")) { #endif using (var context = new UnitOfWorkScope()) { var user = User.GetById(userId); if (user != null) { user.SetPassword(password); } var validationResults = new UserValidator() .Validate(user); if (validationResults.IsValid) { context.Commit(); UserCacheManager.Put(user); return new FacadeResult<User>(user); } var error = validationResults.Errors .First().ErrorMessage .GetError(); return new FacadeResult<User>(error); } #if DEBUG } #endif }
public void UnitOfWork_Rolledback_When_Containing_TransactionScope_Is_Rolledback() { using (var testData = new Db4oTestDataGenerator(_db4oServer.OpenClient())) { testData.Batch(actions => actions.CreateOrderForCustomer(actions.CreateCustomer())); int orderId; DateTime oldDate; using (var txScope = new TransactionScope(TransactionScopeOption.Required)) using (var uowScope = new UnitOfWorkScope(IsolationLevel.Serializable)) { var ordersRepository = new Db4oRepository<Order>(); var order = (from o in ordersRepository select o).First(); oldDate = order.OrderDate; order.OrderDate = DateTime.Now; orderId = order.OrderID; uowScope.Commit(); //Note: txScope has not been committed } using (new UnitOfWorkScope()) { var ordersRepository = new Db4oRepository<Order>(); var order = (from o in ordersRepository where o.OrderID == orderId select o).First(); Assert.That(order.OrderDate, Is.EqualTo(oldDate)); } } }
public void Can_save() { int customerId; using (var scope = new UnitOfWorkScope()) { var customer = new Customer { FirstName = "Jane", LastName = "Doe", StreetAddress1 = "123 Main St.", }; new EFRepository<Customer>().Add(customer); scope.Commit(); customerId = customer.CustomerID; } var savedCustomer = new EFTestData(Context) .Get<Customer>(x => x.CustomerID == customerId); Assert.That(savedCustomer, Is.Not.Null); }
public void Can_perform_simple_query() { var testData = new EFTestData(Context); Customer customer = null; testData.Batch(x => customer = x.CreateCustomer()); using (var scope = new UnitOfWorkScope()) { var savedCustomer = new EFRepository<Customer>() .First(x => x.CustomerID == customer.CustomerID); Assert.That(savedCustomer, Is.Not.Null); scope.Commit(); } }
/// <summary> /// Gets a <see cref="UnitOfWorkScopeTransaction"/> instance that can be used by a <see cref="UnitOfWorkScope"/> instance. /// </summary> /// <param name="scope">The <see cref="UnitOfWorkScope"/> instance that is requesting the transaction.</param> /// <param name="isolationLevel">One of the values of <see cref="IsolationLevel"/> that specifies the transaction isolation level.</param> /// <param name="options">One of the values of <see cref="UnitOfWorkScopeTransactionOptions"/> that specifies options for using existing /// transacitons or creating new ones.</param> /// <returns>A <see cref="UnitOfWorkScopeTransaction"/> instance.</returns> public static UnitOfWorkScopeTransaction GetTransactionForScope(UnitOfWorkScope scope, IsolationLevel isolationLevel, UnitOfWorkScopeTransactionOptions options) { var useCompatibleTx = (options & UnitOfWorkScopeTransactionOptions.UseCompatible) == UnitOfWorkScopeTransactionOptions.UseCompatible; var createNewTx = (options & UnitOfWorkScopeTransactionOptions.CreateNew) == UnitOfWorkScopeTransactionOptions.CreateNew; Guard.Against<InvalidOperationException>(useCompatibleTx && createNewTx, "Cannot start a transaction with both UseCompatible and CreateNew specified " + "as a UnitOfWorkScopeTransactionOptions"); if (options == UnitOfWorkScopeTransactionOptions.UseCompatible) { var transaction = (from t in CurrentTransactions where t.IsolationLevel == isolationLevel select t).FirstOrDefault(); if (transaction != null) { transaction.AttachScope(scope); return transaction; } } var factory = ServiceLocator.Current.GetInstance<IUnitOfWorkFactory>(); var newTransaction = new UnitOfWorkScopeTransaction(factory, isolationLevel); newTransaction.AttachScope(scope); CurrentTransactions.AddFirst(newTransaction); return newTransaction; }
/// <summary> /// Gets a <see cref="UnitOfWorkScopeTransaction"/> instance that can be used by a <see cref="UnitOfWorkScope"/> instance. /// </summary> /// <param name="scope">The <see cref="UnitOfWorkScope"/> instance that is requesting the transaction.</param> /// <param name="isolationLevel">One of the values of <see cref="IsolationLevel"/> that specifies the transaction isolation level.</param> /// <returns>A <see cref="UnitOfWorkScopeTransaction"/> instance.</returns> public static UnitOfWorkScopeTransaction GetTransactionForScope(UnitOfWorkScope scope, IsolationLevel isolationLevel) { return GetTransactionForScope(scope, isolationLevel, UnitOfWorkScopeTransactionOptions.UseCompatible); }
public FacadeResult<User> UpdateUserProfile(long userId, string name, string email) { #if DEBUG using (MiniProfiler.Current.Step("AccountFacade.UpdateUserProfile")) { #endif using (var context = new UnitOfWorkScope()) { var user = User.GetById(userId); if (user != null) { user.Name = (name ?? "").Trim(); user.Email = (email ?? "").Trim().ToLower(); } var validationResults = new UserValidator() .Validate(user); if (validationResults.IsValid) { context.Commit(); UserCacheManager.Put(user); return new FacadeResult<User>(user); } var error = validationResults.Errors .First().ErrorMessage .GetError(); return new FacadeResult<User>(error); } } #if DEBUG }
public void Save_Does_Not_Save_New_Customer_When_UnitOfWork_Is_Aborted() { var rnd = new Random(); var newAddress = new Address { StreetAddress1 = "This record was inserted via a test", City = "Fictional city", State = "LA", ZipCode = "12345" }; var newCustomer = new Customer { FirstName = ("John_" + rnd.Next(60000, 80000)), LastName = ("Doe_" + rnd.Next(60000, 80000)), Address = newAddress }; using (new UnitOfWorkScope()) { var customerRepository = new Db4oRepository<Customer>(); var recordCheckResult = (from cust in customerRepository where cust.FirstName == newCustomer.FirstName && cust.LastName == newCustomer.LastName select cust).FirstOrDefault(); Assert.That(recordCheckResult, Is.Null); customerRepository.Add(newCustomer); //DO NOT CALL COMMIT TO SIMMULATE A ROLLBACK. } //Starting a completely new unit of work and repository to check for existance. using (var scope = new UnitOfWorkScope()) { var customerRepository = new Db4oRepository<Customer>(); var recordCheckResult = (from cust in customerRepository where cust.FirstName == newCustomer.FirstName && cust.LastName == newCustomer.LastName select cust).FirstOrDefault(); Assert.That(recordCheckResult, Is.Null); scope.Commit(); } }
public void Save_New_Customer_Saves_Customer_When_UnitOfWork_Is_Committed() { var newAddress = new Address { StreetAddress1 = "This record was inserted via a test", City = "Fictional city", State = "LA", ZipCode = "12345" }; var newCustomer = new Customer { FirstName = ("John_" + DateTime.Now), LastName = ("Doe_" + DateTime.Now), Address = newAddress }; var queryForCustomer = new Func<Db4oRepository<Customer>, Customer> ( x => (from cust in x where cust.FirstName == newCustomer.FirstName && cust.LastName == newCustomer.LastName select cust).FirstOrDefault() ); using (var scope = new UnitOfWorkScope()) { var customerRepository = new Db4oRepository<Customer>(); var recordCheckResult = queryForCustomer(customerRepository); Assert.That(recordCheckResult, Is.Null); customerRepository.Add(newCustomer); scope.Commit(); } //Starting a completely new unit of work and repository to check for existance. using (var scope = new UnitOfWorkScope()) { var customerRepository = new Db4oRepository<Customer>(); var recordCheckResult = queryForCustomer(customerRepository); Assert.That(recordCheckResult, Is.Not.Null); Assert.That(recordCheckResult.FirstName, Is.EqualTo(newCustomer.FirstName)); Assert.That(recordCheckResult.LastName, Is.EqualTo(newCustomer.LastName)); scope.Commit(); } }
public void Nested_UnitOfWork_With_Different_Transaction_Compatibility_Works() { var changedShipDate = DateTime.Now.AddDays(1); var changedOrderDate = DateTime.Now.AddDays(2); using (var testData = new Db4oTestDataGenerator(_db4oServer.OpenClient())) { testData.Batch(actions => actions.CreateOrderForCustomer(actions.CreateCustomer())); int orderId; using (new UnitOfWorkScope()) { var ordersRepository = new Db4oRepository<Order>(); orderId = ordersRepository.Select(x => x.OrderID).First(); } Assert.NotNull(orderId); using (new UnitOfWorkScope()) { var outerRepository = new Db4oRepository<Order>(); var outerOrder = outerRepository.Where(x => x.OrderID == orderId).First(); outerOrder.OrderDate = changedOrderDate; using (var innerScope = new UnitOfWorkScope(UnitOfWorkScopeTransactionOptions.CreateNew)) { var innerRepository = new Db4oRepository<Order>(); var innerOrder = innerRepository.Where(x => x.OrderID == orderId).First(); innerOrder.ShipDate = changedShipDate; innerScope.Commit(); } } using (new UnitOfWorkScope()) { var ordersRepository = new Db4oRepository<Order>(); var order = ordersRepository.First(); Assert.That(order.OrderDate, Is.Not.EqualTo(changedOrderDate)); Assert.That(order.ShipDate, Is.Not.EqualTo(changedShipDate)); } } }
public void Can_modify() { Customer customer = null; var testData = new EFTestData(Context); testData.Batch(x => customer = x.CreateCustomer()); using (var scope = new UnitOfWorkScope()) { var savedCustomer = new EFRepository<Customer>() .First(x => x.CustomerID == customer.CustomerID); savedCustomer.FirstName = "Changed"; scope.Commit(); } testData.Refresh(customer); Assert.That(customer.FirstName, Is.EqualTo("Changed")); }
/// <summary> /// Causes a comit operation on the <see cref="UnitOfWorkScopeTransaction"/> instance. /// </summary> /// <param name="scope">The <see cref="UnitOfWorkScope"/> instance that is calling the commit.</param> /// <remarks> /// This method can only by called by the scope currently on top of the stack. If Called by another scope then an /// <see cref="InvalidOperationException"/> is called. If the calling scope is last in the attached scope hierarchy, /// then a commit is called on the underling unit of work instance. /// </remarks> public void Commit(UnitOfWorkScope scope) { Guard.Against<ObjectDisposedException>(_disposed, "Transaction has been disposed. Cannot commit a disposed transaction."); Guard.Against<InvalidOperationException>(_transactionRolledback, "Cannot call commit on a rolledback transaction. A child scope or current scope has already rolled back the transaction. Call Rollback()"); Guard.Against<ArgumentNullException>(scope == null, "Cannot commit the transaction for a null UnitOfWorkScope instance."); Guard.Against<InvalidOperationException>(_attachedScopes.Peek() != scope, "Commit can only be called by the current UnitOfWorkScope instance. The UnitOfWorkScope provided does not match the current scope on the stack."); var currentScope = _attachedScopes.Pop(); if (_attachedScopes.Count != 0) return; //The calling UnitOfWorkScope is the root of the transaction. try { _unitOfWork.Flush(); _runningTransaction.Commit(); _runningTransaction.Dispose(); _unitOfWork.Dispose(); CurrentTransactions.Remove(this); } catch { _attachedScopes.Push(currentScope); throw; } }
public void Can_query_using_specification() { var testData = new EFTestData(Context); testData.Batch(x => { x.CreateCustomer(customer => customer.State = "CA"); x.CreateCustomer(customer => customer.State = "CA"); x.CreateCustomer(customer => customer.State = "PA"); }); using (var scope = new UnitOfWorkScope()) { var specification = new Specification<Customer>(x => x.State == "CA"); var results = new EFRepository<Customer>() .Query(specification); Assert.That(results.Count(), Is.EqualTo(2)); scope.Commit(); } }
/// <summary> /// Causes a Rollback operation on the <see cref="UnitOfWorkScopeTransaction"/> instance. /// </summary> /// <param name="scope">The <see cref="UnitOfWorkScope"/> instance that is calling the commit.</param> /// <remarks> /// This method can only be called by the scope currently on top of the stack. If called by another scope than the /// current <see cref="UnitOfWorkScope"/> instance, then a <see cref="InvalidOperationException"/> is thrown. If the /// calling scope is the last in the attached scope hierarchy, then a rollback is called on the underlying UnitOfWork /// instance. /// </remarks> public void Rollback(UnitOfWorkScope scope) { Guard.Against<ObjectDisposedException>(_disposed, "Transaction has been disposed. Cannot rollback a disposed transaction."); Guard.Against<ArgumentNullException>(scope == null, "Cannot rollback the transaction for a null UnitOfWork instance."); Guard.Against<InvalidOperationException>(_attachedScopes.Peek() != scope, "Rollback can only be called by the current UnitOfWorkScope instance. The UnitOfWorkScope provided does not match the current scope on the stack."); _transactionRolledback = true; _attachedScopes.Pop(); if (_attachedScopes.Count != 0) return; //The calling UnitOfWorkScope is the root of the transaction. _runningTransaction.Rollback(); _runningTransaction.Dispose(); _unitOfWork.Dispose(); CurrentTransactions.Remove(this); }
public void throws_when_lazyloading_outside_of_scope() { Order order = null; var testData = new EFTestData(Context); testData.Batch(x => order = x.CreateOrderForCustomer(x.CreateCustomer())); Order savedOrder = null; using (var scope = new UnitOfWorkScope()) { savedOrder = new EFRepository<Order>() .First(x => x.OrderID == order.OrderID); scope.Commit(); } Assert.That(savedOrder, Is.Not.Null); Assert.Throws<ObjectDisposedException>(() => { var fname = savedOrder.Customer.FirstName; }); }
/// <summary> /// Attaches a <see cref="UnitOfWorkScope"/> instance to the <see cref="UnitOfWorkScopeTransaction"/> instance. /// </summary> /// <param name="scope"></param> void AttachScope(UnitOfWorkScope scope) { Guard.Against<ObjectDisposedException>(_disposed, "Transaction has been disposed. Cannot attach a scope to a disposed transaction."); Guard.Against<ArgumentNullException>(scope == null, "Cannot attach a null UnitOfWorkScope instance to the UnitOfWorkScopeTransaction instance."); _attachedScopes.Push(scope); //Push the scope on to the top of the stack. }
/// <summary> /// Gets a <see cref="UnitOfWorkScopeTransaction"/> instance that can be used by a <see cref="UnitOfWorkScope"/> instance. /// </summary> /// <param name="scope">The <see cref="UnitOfWorkScope"/> instance that is requesting the transaction.</param> /// <param name="isolationLevel">One of the values of <see cref="IsolationLevel"/> that specifies the transaction isolation level.</param> /// <returns>A <see cref="UnitOfWorkScopeTransaction"/> instance.</returns> public static UnitOfWorkScopeTransaction GetTransactionForScope(UnitOfWorkScope scope, IsolationLevel isolationLevel) { return(GetTransactionForScope(scope, isolationLevel, UnitOfWorkScopeTransactionOptions.UseCompatible)); }
public void Save_Updates_Existing_Order_Record() { var updatedDate = DateTime.Now; using (var testData = new Db4oTestDataGenerator(_db4oServer.OpenClient())) { testData.Batch(actions => actions.CreateOrderForCustomer(actions.CreateCustomer())); int orderId; using (var scope = new UnitOfWorkScope()) { var orderRepository = new Db4oRepository<Order>(); var order = orderRepository.FirstOrDefault(); Assert.That(order, Is.Not.Null); orderId = order.OrderID; order.OrderDate = updatedDate; orderRepository.Save(order); //Db4o does not do change tracking! scope.Commit(); } using (new UnitOfWorkScope()) { var orderRepository = new Db4oRepository<Order>(); var order = (from o in orderRepository where o.OrderID == orderId select o).FirstOrDefault(); Assert.That(order, Is.Not.Null); Assert.That(order.OrderDate.Date, Is.EqualTo(updatedDate.Date)); Assert.That(order.OrderDate.Hour, Is.EqualTo(updatedDate.Hour)); Assert.That(order.OrderDate.Minute, Is.EqualTo(updatedDate.Minute)); Assert.That(order.OrderDate.Second, Is.EqualTo(updatedDate.Second)); } } }