public void InsertProducts()
        {
            using (IDataContextAsync context = new NorthwindContext())
            using (IUnitOfWorkAsync unitOfWork = new UnitOfWork(context))
            {
                IRepositoryAsync<Product> productRepository = new Repository<Product>(context, unitOfWork);

                var newProducts = new[]
                {
                    new Product {ProductName = "One", Discontinued = false, ObjectState = ObjectState.Added},
                    new Product {ProductName = "12345678901234567890123456789012345678901234567890", Discontinued = true, ObjectState = ObjectState.Added},
                    new Product {ProductName = "Three", Discontinued = true, ObjectState = ObjectState.Added},
                    new Product {ProductName = "Four", Discontinued = true, ObjectState = ObjectState.Added},
                    new Product {ProductName = "Five", Discontinued = true, ObjectState = ObjectState.Added}
                };

                foreach (var product in newProducts)
                {
                    try
                    {
                        productRepository.Insert(product);
                        unitOfWork.SaveChanges();
                    }
                    catch (DbEntityValidationException ex)
                    {
                        var sb = new StringBuilder();

                        foreach (var failure in ex.EntityValidationErrors)
                        {
                            sb.AppendFormat("{0} failed validation\n", failure.Entry.Entity.GetType());

                            foreach (var error in failure.ValidationErrors)
                            {
                                sb.AppendFormat("- {0} : {1}", error.PropertyName, error.ErrorMessage);
                                sb.AppendLine();
                            }
                        }

                        Debug.WriteLine(sb.ToString());
                        TestContext.WriteLine(sb.ToString());
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine(ex.Message);
                        TestContext.WriteLine(ex.Message);
                    }
                }

                var insertedProduct = productRepository.Query(x => x.ProductName == "One").Select().FirstOrDefault();
                Assert.IsTrue(insertedProduct.ProductName == "One");
            }
        }
        public void UnitOfWork_Transaction_Test()
        {
            using(IDataContextAsync context = new NorthwindContext())
            using (IUnitOfWorkAsync unitOfWork = new UnitOfWork(context))
            {
                using (IUnitOfWorkAsync unitOfWorkAsync = new UnitOfWork(context))
                {
                    IRepositoryAsync<Customer> customerRepository = new Repository<Customer>(context, unitOfWork);
                
                    IService<Customer> customerService = new CustomerService(customerRepository, unitOfWorkAsync);

                    try
                    {
                        unitOfWork.BeginTransaction();
                
                        customerService.Insert(new Customer { CustomerID = "YODA", CompanyName = "SkyRanch", ObjectState = ObjectState.Added});
                        customerService.Insert(new Customer { CustomerID = "JEDI", CompanyName = "SkyRanch", ObjectState = ObjectState.Added});

                        var customer = customerService.Find("YODA");
                        Assert.AreSame(customer.CustomerID, "YODA");

                        customer = customerService.Find("JEDI");
                        Assert.AreSame(customer.CustomerID, "JEDI");

                        // save
                        var saveChangesAsync = unitOfWork.SaveChanges();
                        //Assert.AreSame(saveChangesAsync, 2);

                        // Will cause an exception, cannot insert customer with the same CustomerId (primary key constraint)
                        customerService.Insert(new Customer { CustomerID = "JEDI", CompanyName = "SkyRanch", ObjectState = ObjectState.Added });
                        //save 
                        unitOfWork.SaveChanges();

                        unitOfWork.Commit();
                    }
                    catch (Exception e)
                    {
                        unitOfWork.Rollback();
                    }
                }
            }
        }
        public void UnitOfWork_Dispose_Test()
        {
            IDataContextAsync context = new NorthwindContext();
            IUnitOfWorkAsync unitOfWork = new UnitOfWork(context);

            // opening connection
            unitOfWork.BeginTransaction();
            unitOfWork.Commit();

            // calling dispose 1st time
            unitOfWork.Dispose();
            var isDisposed = (bool) GetInstanceField(typeof (UnitOfWork), unitOfWork, "_disposed");
            Assert.IsTrue(isDisposed);

            // calling dispose 2nd time, should not throw any excpetions
            unitOfWork.Dispose();
            context.Dispose();

            // calling dispose 3rd time, should not throw any excpetions
            context.Dispose();
            unitOfWork.Dispose();
        }
        public void CreateCustomerTest()
        {
            // Create new customer
            using (IDataContextAsync context = new NorthwindContext())
            using (IUnitOfWorkAsync unitOfWork = new UnitOfWork(context))
            {
                IRepositoryAsync<Customer> customerRepository = new Repository<Customer>(context, unitOfWork);

                var customer = new Customer
                {
                    CustomerID = "LLE37",
                    CompanyName = "CBRE",
                    ContactName = "Long Le",
                    ContactTitle = "App/Dev Architect",
                    Address = "11111 Sky Ranch",
                    City = "Dallas",
                    PostalCode = "75042",
                    Country = "USA",
                    Phone ="(222) 222-2222",
                    Fax = "(333) 333-3333",
                    ObjectState = ObjectState.Added,
                };

                customerRepository.Insert(customer);
                unitOfWork.SaveChanges();
            }

            //  Query for newly created customer by ID from a new context, to ensure it's not pulling from cache
            using (IDataContextAsync context = new NorthwindContext())
            using (IUnitOfWorkAsync unitOfWork = new UnitOfWork(context))
            {
                IRepositoryAsync<Customer> customerRepository = new Repository<Customer>(context, unitOfWork);
                var customer = customerRepository.Find("LLE37");
                Assert.AreEqual(customer.CustomerID, "LLE37"); 
            }
        }
        public void CreateOrderObjectGraphTest()
        {
            using (IDataContextAsync context = new NorthwindContext())
            using (IUnitOfWorkAsync unitOfWork = new UnitOfWork(context))
            {
                IRepositoryAsync<Order> orderRepository = new Repository<Order>(context, unitOfWork);

                var orderTest = new Order
                {
                    CustomerID = "LLE39",
                    EmployeeID = 10,
                    OrderDate = DateTime.Now,
                    ObjectState = ObjectState.Added,

                    Employee = new Employee
                    {
                        EmployeeID = 10,
                        FirstName = "Test",
                        LastName = "Le",
                        ObjectState = ObjectState.Added
                    },

                    OrderDetails = new List<OrderDetail>
                    {
                        new OrderDetail
                        {
                            ProductID = 1,
                            Quantity = 5,
                            ObjectState = ObjectState.Added
                        },
                        new OrderDetail
                        {
                            ProductID = 2,
                            Quantity = 5,
                            ObjectState = ObjectState.Added
                        }
                    }
                };

                orderRepository.InsertOrUpdateGraph(orderTest);

                try
                {
                    unitOfWork.SaveChanges();
                }
                catch (DbEntityValidationException ex)
                {
                    var sb = new StringBuilder();

                    foreach (var failure in ex.EntityValidationErrors)
                    {
                        sb.AppendFormat("{0} failed validation\n", failure.Entry.Entity.GetType());

                        foreach (var error in failure.ValidationErrors)
                        {
                            sb.AppendFormat("- {0} : {1}", error.PropertyName, error.ErrorMessage);
                            sb.AppendLine();
                        }
                    }

                    Debug.WriteLine(sb.ToString());
                    TestContext.WriteLine(sb.ToString());
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                    TestContext.WriteLine(ex.Message);
                }
            }
        }
        public void CreateAndUpdateAndDeleteCustomerGraphTest()
        {
            // Create new customer
            using (IDataContextAsync context = new NorthwindContext())
            using (IUnitOfWorkAsync unitOfWork = new UnitOfWork(context))
            {
                IRepositoryAsync<Customer> customerRepository = new Repository<Customer>(context, unitOfWork);

                var customerForInsertGraphTest = new Customer
                {
                    CustomerID = "LLE38",
                    CompanyName = "CBRE",
                    ContactName = "Long Le",
                    ContactTitle = "App/Dev Architect",
                    Address = "11111 Sky Ranch",
                    City = "Dallas",
                    PostalCode = "75042",
                    Country = "USA",
                    Phone = "(222) 222-2222",
                    Fax = "(333) 333-3333",
                    ObjectState = ObjectState.Added,
                    Orders = new[]
                    {
                        new Order()
                        {
                            CustomerID = "LLE38",
                            EmployeeID = 1,
                            OrderDate = DateTime.Now,
                            ObjectState = ObjectState.Added,
                        }, 
                        new Order()
                        {
                            CustomerID = "LLE39",
                            EmployeeID = 1,
                            OrderDate = DateTime.Now,
                            ObjectState = ObjectState.Added
                        }, 
                    }
                };

                customerRepository.InsertOrUpdateGraph(customerForInsertGraphTest);
                unitOfWork.SaveChanges();
            }

            Customer customerForUpdateDeleteGraphTest = null;

            //  Query for newly created customer by ID from a new context, to ensure it's not pulling from cache
            using (IDataContextAsync context = new NorthwindContext())
            using (IUnitOfWorkAsync unitOfWork = new UnitOfWork(context))
            {
                IRepositoryAsync<Customer> customerRepository = new Repository<Customer>(context, unitOfWork);
                
                 customerForUpdateDeleteGraphTest = customerRepository
                    .Query(x => x.CustomerID == "LLE38")
                    .Include(x => x.Orders)
                    .Select()
                    .SingleOrDefault();

                // Testing that customer was created
                Assert.AreEqual(customerForUpdateDeleteGraphTest.CustomerID, "LLE38");

                // Testing that orders in customer graph were created
                Assert.IsTrue(customerForUpdateDeleteGraphTest.Orders.Count == 2);

                // Make changes to the object graph while in this context, will save these 
                // changes in another context, testing managing states between and/or while disconnected
                // from the orginal DataContext

                // Updating the customer in the graph
                customerForUpdateDeleteGraphTest.City = "Houston";
                customerForUpdateDeleteGraphTest.ObjectState = ObjectState.Modified;

                // Updating the order in the graph
                var firstOrder = customerForUpdateDeleteGraphTest.Orders.Take(1).Single();
                firstOrder.ShipCity = "Houston";
                firstOrder.ObjectState = ObjectState.Modified;

                // Deleting one of the orders from the graph
                var secondOrder = customerForUpdateDeleteGraphTest.Orders.Skip(1).Take(1).Single();
                secondOrder.ObjectState = ObjectState.Deleted;
            }

            //  Query for newly created customer by ID from a new context, to ensure it's not pulling from cache
            using (IDataContextAsync context = new NorthwindContext())
            using (IUnitOfWorkAsync unitOfWork = new UnitOfWork(context))
            {
                IRepositoryAsync<Customer> customerRepository = new Repository<Customer>(context, unitOfWork);

                // Testing changes to graph while disconncted from it's orginal DataContext
                // Saving changes while graph was previous DataContext that was already disposed
                customerRepository.InsertOrUpdateGraph(customerForUpdateDeleteGraphTest);
                unitOfWork.SaveChanges();

                customerForUpdateDeleteGraphTest = customerRepository
                    .Query(x => x.CustomerID == "LLE38")
                    .Include(x => x.Orders)
                    .Select()
                    .SingleOrDefault();

                Assert.AreEqual(customerForUpdateDeleteGraphTest.CustomerID, "LLE38");

                // Testing for order(2) was deleted from the graph
                Assert.IsTrue(customerForUpdateDeleteGraphTest.Orders.Count == 1);

                // Testing that customer was updated in the graph
                Assert.IsTrue(customerForUpdateDeleteGraphTest.City == "Houston");

                // Testing that order was updated in the graph.
                Assert.IsTrue(customerForUpdateDeleteGraphTest.Orders.ToArray()[0].ShipCity == "Houston");
            }
        }
        public void GetCustomersAsync()
        {
            using (IDataContextAsync context = new NorthwindContext())
            using (IUnitOfWorkAsync unitOfWork = new UnitOfWork(context))
            {
                IRepositoryAsync<Customer> customerRepository = new Repository<Customer>(context, unitOfWork);
                ICustomerService customerService = new CustomerService(customerRepository, unitOfWork);

                var asyncTask = customerService
                    .Query(x => x.Country == "USA")
                    .Include(x => x
                        .Orders
                        .Select(y => y.OrderDetails))
                    .OrderBy(x => x
                        .OrderBy(y => y.CompanyName)
                        .ThenBy(z => z.ContactName))
                    .SelectAsync();

                var customers = asyncTask.Result;

                Assert.IsTrue(customers.Count() > 1);
                Assert.IsFalse(customers.Count(x => x.Country == "USA") == 0);
            }
        }
 public void CustomerOrderTotalByYear()
 {
     using (IDataContextAsync context = new NorthwindContext())
     using (IUnitOfWorkAsync unitOfWork = new UnitOfWork(context))
     {
         IRepositoryAsync<Customer> customerRepository = new Repository<Customer>(context, unitOfWork);
         ICustomerService customerService = new CustomerService(customerRepository, unitOfWork);
         var customerOrderTotalByYear = customerService.CustomerOrderTotalByYear("ALFKI", 1998);
         Assert.AreEqual(customerOrderTotalByYear, (decimal)2302.2000);
     }
 }
 public void FindCustomerById_Test()
 {
     using (IDataContextAsync context = new NorthwindContext())
     using (IUnitOfWorkAsync unitOfWork = new UnitOfWork(context))
     {
         IRepositoryAsync<Customer> customerRepository = new Repository<Customer>(context, unitOfWork);
         IService<Customer> customerService = new CustomerService(customerRepository, unitOfWork);
         var customer = customerService.Find("ALFKI");
         TestContext.WriteLine("Customers found: {0}", customer.ContactName);
         Assert.AreEqual(customer.ContactName, "Maria Anders");
     }
 }
 public void GetCustomerOrderTest()
 {
     using (IDataContextAsync context = new NorthwindContext())
     using (IUnitOfWorkAsync unitOfWork = new UnitOfWork(context))
     {
         IRepositoryAsync<Customer> customerRepository = new Repository<Customer>(context, unitOfWork);
         var customerOrders = customerRepository.GetCustomerOrder("USA");
         var enumerable = customerOrders as CustomerOrder[] ?? customerOrders.ToArray();
         TestContext.WriteLine("Customers found: {0}", enumerable.Count());
         Assert.IsTrue(enumerable.Any());
     }
 }