private void ParseFoodGroupFileAndInsertIntoCategoryTable(PantryPlannerContext context)
        {
            // validate file exists
            string fullPath = TxtRootFolderPath + FoodGroupFileName;

            if (File.Exists(fullPath) == false)
            {
                throw new FileNotFoundException($"Could not find {FoodGroupFileName} at the specified path", fullPath);
            }


            // ensure CategoryType 'Ingredient' exists
            CategoryType ingredientCategoryType;

            if (context.CategoryType.Any(c => c.Name == "Ingredient") == false)
            {
                ingredientCategoryType = new CategoryType()
                {
                    Name = "Ingredient"
                };

                context.CategoryType.Add(ingredientCategoryType);
                context.SaveChanges();
            }
            else
            {
                ingredientCategoryType = context.CategoryType.Where(c => c.Name == "Ingredient").FirstOrDefault();
            }

            List <Category> categoriesToAdd = new List <Category>();

            foreach (string line in File.ReadAllLines(fullPath))
            {
                // parse line by format rules (each field is seperated by ^)
                List <string> fieldValues = line.Split("^").ToList();

                // get code and food group name (trim ~ based on format rules)
                string code          = fieldValues[0].Trim('~');
                string foodGroupDesc = fieldValues[1].Trim('~');

                // check if food group name already exists in context
                bool categoryExists = context.Category.Any(c => c.Name == foodGroupDesc && c.CategoryTypeId == ingredientCategoryType.CategoryTypeId);

                if (categoryExists)
                {
                    continue;
                }

                // add food group as an Ingredient category
                Category newFoodGroup = new Category()
                {
                    CategoryTypeId = ingredientCategoryType.CategoryTypeId,
                    Name           = foodGroupDesc
                };

                categoriesToAdd.Add(newFoodGroup);
            }

            if (categoriesToAdd.Count > 0)
            {
                context.Category.AddRange(categoriesToAdd);
                context.SaveChanges();
            }


            // Map out IDs to codes for later inserting ingredients
            foreach (string line in File.ReadAllLines(fullPath))
            {
                // parse line by format rules (each field is seperated by ^)
                List <string> fieldValues = line.Split("^").ToList();

                // get code and food group name (trim ~ based on format rules)
                string code          = fieldValues[0].Trim('~');
                string foodGroupDesc = fieldValues[1].Trim('~');

                Category existingCategory = context.Category.Where(c => c.Name == foodGroupDesc && c.CategoryTypeId == ingredientCategoryType.CategoryTypeId).FirstOrDefault();

                if (existingCategory != null)
                {
                    FoodGroupCodeToCategoryId.TryAdd(code, existingCategory.CategoryId);
                }
            }
        }
        private void ParseFoodDescriptionFileAndInsertIntoIngredientTable(PantryPlannerContext context, int maxRowsToProcess = -1)
        {
            int lineCount = 0;
            List <Ingredient> ingredientsToAdd = new List <Ingredient>();

            // validate file exists
            string fullPath = TxtRootFolderPath + FoodDescriptionFileName;

            if (File.Exists(fullPath) == false)
            {
                throw new FileNotFoundException($"Could not find {FoodDescriptionFileName} at the specified path", fullPath);
            }


            foreach (string line in File.ReadAllLines(fullPath))
            {
                if (maxRowsToProcess != -1 && lineCount >= maxRowsToProcess)
                {
                    break; // stop parsing after reaching the max row count passed in
                }

                lineCount++;

                // parse line by format rules (each field is seperated by ^)
                List <string> fieldValues = line.Split("^").ToList();

                string nutrientDBID    = fieldValues[FoodDescColumnNameToIndex["NDBID"]].Trim('~');
                string foodGroupCode   = fieldValues[FoodDescColumnNameToIndex["FoodGrpCode"]].Trim('~');
                string longDescription = fieldValues[FoodDescColumnNameToIndex["LongDesc"]].Trim('~');
                string commonNames     = fieldValues[FoodDescColumnNameToIndex["ComName"]].Trim('~');

                FoodGroupCodeToCategoryId.TryGetValue(foodGroupCode, out long foodGroupCategoryId);

                if (foodGroupCategoryId == 0)
                {
                    continue; // unknown food category, lets skip
                }


                bool categoryExists = context.Ingredient.Any(i => i.CategoryId == foodGroupCategoryId && i.Name == longDescription);

                if (categoryExists)
                {
                    continue;
                }

                Ingredient newIngredient = new Ingredient()
                {
                    Name        = longDescription,
                    CategoryId  = foodGroupCategoryId,
                    IsPublic    = true,
                    DateAdded   = DateTime.Now,
                    Description = ""
                };

                ingredientsToAdd.Add(newIngredient);
            }

            if (ingredientsToAdd.Count > 0)
            {
                context.Ingredient.AddRange(ingredientsToAdd);
                context.SaveChanges();
            }
        }