static void Main(string[] args)
        {
            int startRow = 0;

            // Remove all record from the Person document
            var docUnitOfWork = new FootlooseFSDocUnitOfWork();
            docUnitOfWork.Persons.DeleteAll();

            while (true)
            {
                using (var sqlUnitOfWork = new FootlooseFSSqlUnitOfWork())
                {
                    IQueryable<Person> personQueryable = sqlUnitOfWork.Persons.GetQueryable();

                    // For each person retreived from SQL include the related phones and addresses
                    personQueryable = personQueryable.Include("Addresses.Address").Include("Phones");

                    // Always order by person ID so that we can guarantee the order for the persons retrieved from SQL
                    personQueryable = personQueryable.OrderBy(p => p.PersonID);

                    // Get throttleRate number of persons from SQL
                    List<Person> persons = personQueryable.Skip(startRow)
                                                    .Take(throttleRate)
                                                    .ToList();

                    if (persons.Count > 0)
                    {
                        IEnumerable<PersonDocument> personDocuments = from p in persons
                                                                      select new PersonDocument
                                                                      {
                                                                          PersonID = p.PersonID,
                                                                          FirstName = p.FirstName,
                                                                          LastName = p.LastName,
                                                                          EmailAddress = p.EmailAddress,
                                                                          PhoneNumber = p.Phones != null && p.Phones.Any(h => h.PhoneTypeID == 1) ? p.Phones.First(h => h.PhoneTypeID == 1).Number : "",
                                                                          StreetAddress = p.Addresses != null && p.Addresses.Any(pa => pa.AddressTypeID == 1) ? p.Addresses.First(pa => pa.AddressTypeID == 1).Address.StreetAddress : "",
                                                                          City = p.Addresses != null && p.Addresses.Any(pa => pa.AddressTypeID == 1) ? p.Addresses.First(pa => pa.AddressTypeID == 1).Address.City : "",
                                                                          State = p.Addresses != null && p.Addresses.Any(pa => pa.AddressTypeID == 1) ? p.Addresses.First(pa => pa.AddressTypeID == 1).Address.State : "",
                                                                          Zip = p.Addresses != null && p.Addresses.Any(pa => pa.AddressTypeID == 1) ? p.Addresses.First(pa => pa.AddressTypeID == 1).Address.Zip : ""
                                                                      };

                        docUnitOfWork.Persons.AddBatch(personDocuments);

                        Console.WriteLine(string.Format("Complete {0} - {1}", startRow, startRow + throttleRate));

                        // If the number of persons retrieved is less than throttleRate then we are finished
                        if (personDocuments.Count() < throttleRate)
                            break;
                    }
                    else
                    {
                        break;
                    }

                }

                // Otherwise move the starting row by throttleRate number of persons
                startRow += throttleRate;
            }
        }
        public PageOfList<PersonDocument> SearchPersonDocuments(int pageNumber, int numRecordsInPage, string sort, SortDirection sortDirection, PersonDocument searchCriteria)
        {
            // Note the Document Unit of Work will be disposed when out of scope (does not require using statement)
            var unitOfWork = new FootlooseFSDocUnitOfWork();

            // Search, sort, and page the results
            return unitOfWork.Persons.Search(pageNumber, numRecordsInPage, searchCriteria, sort, sortDirection);
        }
        public PageOfList<PersonDocument> SearchPersonDocuments(int pageNumber, PersonSearchColumn personSearchColumn, SortDirection sortDirection, int numRecordsInPage, Dictionary<PersonSearchColumn, string> searchCriteria)
        {
            // Search for persons using the Document DB repository
            // Determine the starting row from the pageNumber and numRecordsInPage
            int startRow;
            int totalItemCount = 0;

            if (numRecordsInPage == -1)
                startRow = 0;
            else
                startRow = (pageNumber - 1) * numRecordsInPage;

            PageOfList<PersonDocument> searchResults = null;

            // Note the Document Unit of Work will be disposed when out of scope (does not require using statement)
            var unitOfWork = new FootlooseFSDocUnitOfWork();

            IQueryable<PersonDocument> personsQueryable = unitOfWork.Persons.GetQueryable();

            // For each search criteria given add an appropriate filter to the Person Queryable
            foreach (KeyValuePair<PersonSearchColumn, string> entry in searchCriteria)
            {
                if (entry.Key == PersonSearchColumn.PersonID)
                {
                    var personID = Int32.Parse(entry.Value);
                    personsQueryable = personsQueryable.Where(p => p.PersonID == personID);
                }

                var searchValue = entry.Value.ToLower();

                if (entry.Key == PersonSearchColumn.FirstName)
                    personsQueryable = personsQueryable.Where(p => p.FirstName.ToLower().StartsWith(searchValue));

                if (entry.Key == PersonSearchColumn.LastName)
                    personsQueryable = personsQueryable.Where(p => p.LastName.ToLower().StartsWith(searchValue));

                if (entry.Key == PersonSearchColumn.EmailAddress)
                    personsQueryable = personsQueryable.Where(p => p.EmailAddress.ToLower().StartsWith(searchValue));

                if (entry.Key == PersonSearchColumn.Phone)
                    personsQueryable = personsQueryable.Where(p => p.PhoneNumber.ToLower().StartsWith(searchValue));

                if (entry.Key == PersonSearchColumn.City)
                    personsQueryable = personsQueryable.Where(p => p.City.ToLower().StartsWith(searchValue));

                if (entry.Key == PersonSearchColumn.State)
                    personsQueryable = personsQueryable.Where(p => p.State.ToLower().StartsWith(searchValue));

                if (entry.Key == PersonSearchColumn.StreetAddress)
                    personsQueryable = personsQueryable.Where(p => p.StreetAddress.ToLower().StartsWith(searchValue));

                if (entry.Key == PersonSearchColumn.Zip)
                    personsQueryable = personsQueryable.Where(p => p.Zip.ToLower().StartsWith(searchValue));
            }

            IOrderedQueryable<PersonDocument> personOrderedQueryable = null;

            // Apply the sorting using the requested sort column and direction
            if (sortDirection == SortDirection.Ascending)
            {
                if (personSearchColumn == PersonSearchColumn.PersonID)
                    personOrderedQueryable = personsQueryable.OrderBy(p => p.PersonID);
                else if (personSearchColumn == PersonSearchColumn.FirstName)
                    personOrderedQueryable = personsQueryable.OrderBy(p => p.FirstName);
                else if (personSearchColumn == PersonSearchColumn.LastName)
                    personOrderedQueryable = personsQueryable.OrderBy(p => p.LastName);
                else if (personSearchColumn == PersonSearchColumn.EmailAddress)
                    personOrderedQueryable = personsQueryable.OrderBy(p => p.EmailAddress);
                else if (personSearchColumn == PersonSearchColumn.Phone)
                    personOrderedQueryable = personsQueryable.OrderBy(p => p.PhoneNumber);
                else if (personSearchColumn == PersonSearchColumn.City)
                    personOrderedQueryable = personsQueryable.OrderBy(p => p.City);
                else if (personSearchColumn == PersonSearchColumn.State)
                    personOrderedQueryable = personsQueryable.OrderBy(p => p.State);
                else if (personSearchColumn == PersonSearchColumn.StreetAddress)
                    personOrderedQueryable = personsQueryable.OrderBy(p => p.StreetAddress);
                else if (personSearchColumn == PersonSearchColumn.Zip)
                    personOrderedQueryable = personsQueryable.OrderBy(p => p.Zip);
            }
            else
            {
                if (personSearchColumn == PersonSearchColumn.PersonID)
                    personOrderedQueryable = personsQueryable.OrderByDescending(p => p.PersonID);
                else if (personSearchColumn == PersonSearchColumn.FirstName)
                    personOrderedQueryable = personsQueryable.OrderByDescending(p => p.FirstName);
                else if (personSearchColumn == PersonSearchColumn.LastName)
                    personOrderedQueryable = personsQueryable.OrderByDescending(p => p.LastName);
                else if (personSearchColumn == PersonSearchColumn.EmailAddress)
                    personOrderedQueryable = personsQueryable.OrderByDescending(p => p.EmailAddress);
                else if (personSearchColumn == PersonSearchColumn.Phone)
                    personOrderedQueryable = personsQueryable.OrderByDescending(p => p.PhoneNumber);
                else if (personSearchColumn == PersonSearchColumn.City)
                    personOrderedQueryable = personsQueryable.OrderByDescending(p => p.City);
                else if (personSearchColumn == PersonSearchColumn.State)
                    personOrderedQueryable = personsQueryable.OrderByDescending(p => p.State);
                else if (personSearchColumn == PersonSearchColumn.StreetAddress)
                    personOrderedQueryable = personsQueryable.OrderByDescending(p => p.StreetAddress);
                else if (personSearchColumn == PersonSearchColumn.Zip)
                    personOrderedQueryable = personsQueryable.OrderByDescending(p => p.Zip);
            }

            // Get the number of records
            int recordCount = personOrderedQueryable.Count();

            // Apply the paging
            List<PersonDocument> persons;
            if (numRecordsInPage != -1)
                persons = personOrderedQueryable.Skip(startRow)
                                                .Take(numRecordsInPage)
                                                .ToList();
            else
                persons = personOrderedQueryable.ToList();

            return new PageOfList<PersonDocument>(persons, pageNumber, numRecordsInPage, recordCount);
        }