4

我有一个代表食谱所有成分的类

public class ViewRecipe
{
    public string RecipeName { get; set; }
    public string IngredientName { get; set; }
    public double UnitWeight { get; set; }
    public double TotalWeight { get; set; }

    public ViewRecipe() { }
    public ViewRecipe(string _RecipeName, string _IngredientName, double _UnitWeight, double _TotalWeight)
    {
        RecipeName = _RecipeName;
        IngredientName = _IngredientName;
        UnitWeight = _UnitWeight;
        TotalWeight = _TotalWeight;
    }
}(in reality there are a LOT more data members like quantity, weight, etc....)

实际的数据集是一个名为 ViewRecipeSummary 的列表,它看起来像这样:

RecipeName IngredientName
1          A
1          B
1          C
2          D
2          E
3          A
3          Z

我有一个找到 INGRIDENT (recipeGroup.Key) 的现有查询,我现在需要执行以下操作:

1-找到所有含有该成分的食谱

2-从我的数据中为这些食谱返回所有行

然后我需要在我的查询中使用它(所以它需要使用 LET 或其他东西)

假设我正在寻找所有共享成分 A 的食谱,我希望我的 LET 的最终结果(基于我上面显示的数据)看起来完全像这样:

RecipeName IngredientName
1          A
1          B
1          C
3          A
3          Z

因此,对于任何含有成分 A(1 和 3)的食谱,返回这些食谱的所有行,这样我就有了我需要的所有成分。这应该与我的 ViewRecipe 类采用相同的形式(不是一些新的 {RecipeName, List} 等......),它应该以相同的格式提供相同的数据行。

当前的 LINQ 查询:

            ViewFullRecipeGrouping = (
                from data in ViewRecipeSummary
                group data by data.RecipeName into recipeGroup
                let fullIngredientGroups = recipeGroup.GroupBy(x => x.IngredientName)
                select new ViewFullRecipe()
                {
                    RecipeName = recipeGroup.Key,
                    RecipeIngredients = (
                        from ingredientGroup in fullIngredientGroups
                        select new GroupIngredient()
                        {
                            IngredientName = ingredientGroup.Key,
                        }
                    ).ToList(),
                    ViewGroupRecipes = (

            // THIS IS WHERE I NEED TO ADD MY CODE SO THAT I CAN USE THE RESULT BELOW
            let a = .....
            // BUT I HAVE NO CLUE HOW TO PERFORM SUCH A QUERY HERE

                        select new GroupRecipe()
                        {
            // USE THE RESULTS FOUND TO GENERATE MY RECIPE GROUP
            // BASED ON THE RESULTS FOUND ABOVE
            RecipeName = a.key

                        }).ToList(),
                }).ToList();

就像是:

                    let a = ViewRecipeSummary.GroupBy(x => x.RecipeName)
                        .Where(g => g.Any(x => x.IngredientName == recipeGroup.Key))
                        .Select(g => new ViewRecipe()
                            {
                                RecipeName = g.Key,
                                IngredientName = g.Select(x => x.IngredientName)
                            }) 

但这会返回一个列表,我需要将它分解为相同的结构。

以下是使用的类:

    public class GroupRecipe
    {
        public string RecipeName { get; set; }
        public List<GroupIngredient> Ingredients { get; set; }

        public GroupRecipe() { }
        public GroupRecipe(string _recipeName, List<GroupIngredient> _ingredients)
        {
            RecipeName = _recipeName;
            Ingredients = _ingredients;
        }
    }

   public class GroupIngredient
    {
        public string IngredientName { get; set; }
        public double UnitWeight { get; set; }
        public double TotalWeight { get; set; }

        public GroupIngredient() { }
        public GroupIngredient(string _IngredientName, double _UnitWeight, double _TotalWeight)
        {
            IngredientName = _IngredientName;
            UnitWeight = _UnitWeight;
            TotalWeight = _TotalWeight;
        }
    }
    public class ViewFullRecipe
    {
        public string RecipeName { get; set; }
        public List<GroupIngredient> RecipeIngredients { get; set; }
        public List<GroupRecipe> ViewGroupRecipes { get; set; }

        public ViewFullRecipe() { }
        public ViewFullRecipe(string _RecipeName, List<GroupIngredient> _RecipeIngredients, List<GroupRecipe> _ViewGroupRecipes)
        {
            RecipeName = _RecipeName;
            RecipeIngredients = _RecipeIngredients;
            ViewGroupRecipes = _ViewGroupRecipes;
        }
    }
4

2 回答 2

1

如果我确实理解了您的问题,那么以下代码应该可以工作。正如其他人所说,我确实认为您的查询很复杂,不需要在哪里我认为您可能不想更改一直在工作的内容,我只是保持不变

var viewFullRecipeGrouping =
(
    from data in viewRecipeSummary
    group data by data.RecipeName
    into recipeGroup
    let fullIngredientGroups = recipeGroup.GroupBy(x => x.IngredientName)
    select new ViewFullRecipe()
        {
            RecipeName = recipeGroup.Key,
            RecipeIngredients =
                (
                    from ingredientGroup in fullIngredientGroups
                    select
                        new GroupIngredient
                            {
                                IngredientName = ingredientGroup.Key,
                                UnitWeight = ingredientGroup.Average(r => r.UnitWeight),
                                TotalWeight = ingredientGroup.Sum(r => r.TotalWeight)
                            }
                ).ToList(),

            ViewGroupRecipes =
                (
                    from recipeName in
                        viewRecipeSummary.GroupBy(x => x.IngredientName)
                                            .Where(g => fullIngredientGroups.Any(f => f.Key == g.Key))
                                            .SelectMany(g => g.Select(i => i.RecipeName))
                                            .Distinct()
                    select new GroupRecipe()
                        {
                            RecipeName = recipeName,
                            Ingredients =
                                viewRecipeSummary.Where(v => v.RecipeName == recipeName)
                                                    .GroupBy(i => i.IngredientName)
                                                    .Select(
                                                        g => new GroupIngredient
                                                            {
                                                                IngredientName = g.Key,
                                                                UnitWeight = g.Sum(i => i.UnitWeight),
                                                                TotalWeight = g.Average(i => i.TotalWeight)
                                                            }).ToList()
                        }
                ).ToList()
        }).ToList();
于 2013-04-18T07:32:19.277 回答
0

我假设您的食谱组定义如下:

public class Recipe
{
    public string RecipeName { get; set; }
    public string IngredientName { get; set; }

    public Recipe() { }
    public Recipe(string _recipeName, string _IngredientName)
    {
        RecipeName = _recipeName;
        IngredientName = _IngredientName;
    }
}

public class RecipeGroup
{
    public string RecipeName{get;set;}
    public List<Recipe> Recipe{get;set;}
}

public class RecipeGroupDictionary
{
    private Dictionary<string, List<Recipe>> data;
    public RecipeGroupDictionary()
    {
        data = new Dictionary<string, List<Recipe>>();
    }
    public bool add(Recipe vr)
    {
        this[vr.RecipeName].Add(vr);
        return true;
    }
    public List<Recipe> this[string key]
    {
        get
        {
            if (!data.ContainsKey(key))
                data[key] = new List<Recipe>();
            return data[key];
        }
        set
        {
            data[key] = value;
        }
    }
    public ICollection<string> Keys
    {
        get
        {
            return data.Keys;
        }
    }
    public List<RecipeGroup> getRecipeGroup()
    {
        var result = new List<RecipeGroup>();
        foreach (var key in data.Keys)
        {
            result.Add(new RecipeGroup { RecipeName = key, Recipe = data[key] });
        }
        return result;
    }
}

class Program
{
    static void Main(string[] args)
    {
        var arr = new List<Recipe>();
        var recipeGroup = new RecipeGroupDictionary();
        arr.Add(new Recipe{ RecipeName="1", IngredientName="A"});
        arr.Add(new Recipe{ RecipeName="1", IngredientName="B"});
        arr.Add(new Recipe{ RecipeName="1", IngredientName="C"});
        arr.Add(new Recipe { RecipeName = "2", IngredientName = "B" });
        arr.Add(new Recipe { RecipeName = "2", IngredientName = "C" });
        arr.Add(new Recipe { RecipeName = "3", IngredientName = "A" });
        arr.Add(new Recipe { RecipeName = "3", IngredientName = "X" });
        arr.Add(new Recipe { RecipeName = "3", IngredientName = "Y" });

        var rnset = from row in arr
                    where row.IngredientName == "A"
                    select row.RecipeName;
        var result = (from row in arr
                      where rnset.Contains(row.RecipeName) && recipeGroup.add(row) //Won't be executed if the first condition is false.
                      select row ).ToArray(); //To array is List<Recipe>, if you don't want recipe group you can remove all the recipe dictionary related.
        foreach (var key in recipeGroup.Keys)
        {
            foreach(var recipe in recipeGroup[key])
                Console.WriteLine("RN:{0}, IA:{1}", recipe.RecipeName, recipe.IngredientName);
        }                      
    }
}
于 2013-04-18T02:39:56.703 回答