/// <summary>
        /// Migrate the database into a flatter nosql document structure
        /// </summary>
        public void Migrate()
        {
            Drop(Products, Customers, Sales, Categories);

            using (var db = new AdventureDB())
            {
                MigrateProducts(db);

                MigrateCustomers(db);

                MigrateSales(db);

                MigrateCategories(db);
            }
        }
        private void MigrateSales(AdventureDB db)
        {
            // sales

            var dbSales = db.SalesOrderHeaders
                            .Include(sales => sales.SalesOrderDetails)
                            .ToList();

            Console.WriteLine("Sales - " + dbSales.Count);

            if (dbSales.Any())
            {
                var orders = Mapper.Map<List<MongoSales>>(dbSales);

                Sales.InsertBatch<MongoSales>(orders);
            }
        }
        private void MigrateProducts(AdventureDB db)
        {
            var dbProducts = db.Products.Include(product => product.ProductCategory)
                                        .Include(product => product.ProductModel);

            Console.WriteLine("Products - " + dbProducts.Count());

            Products.InsertBatch<MongoProduct>(Mapper.Map<List<MongoProduct>>(dbProducts.ToList()));
        }
        private void MigrateCustomers(AdventureDB db)
        {
            // customers

            var dbCustomers = db.Customers.Include(cust => cust.CustomerAddresses)
                                          .Include(cust => cust.SalesOrderHeaders);
            var customers = Mapper.Map<List<MongoCustomer>>(dbCustomers.ToList());

            Console.WriteLine("Customers - " + customers.Count);

            foreach (var customer in customers)
            {
                var addresses = from address in db.CustomerAddresses.Include(ca => ca.Address)
                                where address.CustomerID == customer.CustomerID &&
                                      address.Address != null
                                select address.Address;

                var addressList = addresses.Where(ad => ad != null).ToList();
                if (addressList.Any())
                    customer.Addresses.AddRange(Mapper.Map<List<MongoAddress>>(addressList.ToList()));

                var sales = from s in db.SalesOrderHeaders.Include(c => c.SalesOrderDetails)
                            where s.CustomerID == customer.CustomerID &&
                                  s != null
                            select s;

                if (sales.Any())
                {
                    var customerSales = Mapper.Map<List<MongoSales>>(sales.ToList());
                    customer.Sales.AddRange(customerSales);
                }
            }
            Customers.InsertBatch<MongoCustomer>(customers);
        }
        private void MigrateCategories(AdventureDB db)
        {
            var parentCategories = db.ProductCategories.Where(cat => cat.ParentProductCategoryID == null);

            Console.WriteLine("Categories - " + parentCategories.Count());

            foreach (var parentCategory in parentCategories)
            {
                ProductCategory category = parentCategory;
                var childCategories = db.ProductCategories.Where(cat => cat.ParentProductCategoryID == category.ProductCategoryID);

                var mongoCategory = Mapper.Map<MongoCategory>(category);
                mongoCategory.ChildCategories = Mapper.Map<List<MongoCategory>>(childCategories);

                Categories.Insert(mongoCategory);
            }
        }
        public void Migrate()
        {
            using (var db = new AdventureDB())
            {
                var createTableBatch = new TableBatchOperation { };
                var dbProducts = db.Products.Include(x => x.ProductCategory).ToList();

                foreach (var prod in dbProducts)
                {
                    var productTable = prod.AsProductTable();
                    Products.Execute(TableOperation.Insert(productTable));
                }

                //dbProducts.ForEach(product => createTableBatch.Insert(product.AsProductTable()));

                //Products.ExecuteBatch(createTableBatch);
            }
        }