Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用let在LINQ查询中定义一组新数据?_C#_Linq - Fatal编程技术网

C# 如何使用let在LINQ查询中定义一组新数据?

C# 如何使用let在LINQ查询中定义一组新数据?,c#,linq,C#,Linq,我有一个代表食谱所有成分的类 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 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
RecipeName IngredientName
1          A
1          B
1          C
3          A
3          Z
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);
        }                      
    }
}
我有一个查找INGRIDENT(recipeGroup.Key)的现有查询,现在需要执行以下操作:

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

2-从我的数据中返回这些配方的所有行

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

假设我正在寻找所有共享成分A的配方,我希望我的LET的最终结果(基于我上面显示的数据)与此完全相同:

RecipeName IngredientName
1          A
1          B
1          C
2          D
2          E
3          A
3          Z
RecipeName IngredientName
1          A
1          B
1          C
3          A
3          Z
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);
        }                      
    }
}
因此,对于任何含有成分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;
        }
    }
公共类GroupRecipe
{
公共字符串RecipeName{get;set;}
公共列表成分{get;set;}
公共组配方(){}
公共组配方(字符串\u recipeName,列表\u成分)
{
RecipeName=_RecipeName;
配料=_配料;
}
}
公共类组元素
{
公共字符串IngCreditName{get;set;}
公共双单位重量{get;set;}
公共双总权重{get;set;}
公共组元素(){}
PublicGroupComponent(字符串\u IngCreditName、双重单位重量、双重总重量)
{
IngredientName=\u IngredientName;
单位重量=_单位重量;
总重量=_总重量;
}
}
公共类ViewFullRecipe
{
公共字符串RecipeName{get;set;}
公共列表RecipeIngElements{get;set;}
公共列表ViewGroupRecipes{get;set;}
public ViewFullRecipe(){}
公共ViewFullRecipe(字符串_RecipeName、列表_RecipeInElements、列表_ViewGroupRecipes)
{
RecipeName=_RecipeName;
接收要素=_接收要素;
ViewGroupRecipes=\u ViewGroupRecipes;
}
}

我假设您的配方组定义如下:

RecipeName IngredientName
1          A
1          B
1          C
2          D
2          E
3          A
3          Z
RecipeName IngredientName
1          A
1          B
1          C
3          A
3          Z
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);
        }                      
    }
}
公共类配方
{
公共字符串RecipeName{get;set;}
公共字符串IngCreditName{get;set;}
公共配方(){}
公共配方(字符串_recipeName,字符串_IngCreditName)
{
RecipeName=_RecipeName;
IngredientName=\u IngredientName;
}
}
公共类RecipeGroup
{
公共字符串RecipeName{get;set;}
公共列表配方{get;set;}
}
公共类RecipeGroupDictionary
{
专用字典数据;
公共RecipeGroupDictionary()
{
数据=新字典();
}
公共bool添加(配方vr)
{
此[vr.RecipeName].Add(vr);
返回true;
}
公共列表此[字符串键]
{
得到
{
如果(!data.ContainsKey(键))
数据[键]=新列表();
返回数据[键];
}
设置
{
数据[键]=值;
}
}
公共ICollection密钥
{
得到
{
返回数据。键;
}
}
公共列表getRecipeGroup()
{
var result=新列表();
foreach(data.Keys中的var键)
{
Add(新的RecipeGroup{RecipeName=key,Recipe=data[key]});
}
返回结果;
}
}
班级计划
{
静态void Main(字符串[]参数)
{
var arr=新列表();
var recipeGroup=新的RecipeGroupDictionary();
arr.Add(新配方{RecipeName=“1”,IngreditName=“A”});
arr.Add(新配方{RecipeName=“1”,IngreditName=“B”});
arr.Add(新配方{RecipeName=“1”,IngreditName=“C”});
arr.Add(新配方{RecipeName=“2”,IngreditName=“B”});
arr.Add(新配方{RecipeName=“2”,IngreditName=“C”});
arr.Add(新配方{RecipeName=“3”,IngreditName=“A”});
arr.Add(新配方{RecipeName=“3”,IngreditName=“X”});
arr.Add(新配方{RecipeName=“3”,IngreditName=“Y”});
var rnset=来自arr中的行
其中row.IngredientName==“A”
选择row.RecipeName;
var结果=(来自arr中的行
其中,如果第一个条件为false,则不会执行rnset.Contains(row.RecipeName)和&recipeGroup.add(row)//命令。
选择row).ToArray();//To array is List,如果不需要配方组,可以删除所有与配方字典相关的内容。
foreach(往复组合键中的var键)
{
foreach(recipeGroup[key]中的var配方)
WriteLine(“RN:{0},IA:{1}”,recipe.RecipeName,recipe.IngreditName);
}                      
}
}

如果我理解了你的问题,下面的代码应该可以。 正如其他人所说,我确实认为您的查询很复杂,不需要这样做 我想你可能不想改变一直在运作的东西, 我只是保持不变

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();

我假设您正在使用ORM。您是如何生成ORM映射的?通常,ORM映射将为您提供关联(这是实际映射的类的属性)。请包括您的数据库模型类。如果您只想选择成分为“A”的配方,您的查询太复杂。我没有使用ORM,也没有数据库(比如说),它是一个列表格式的数据集合。至于它太复杂了,我不知道你的意思是什么,这是一个预先存在的查询,需要做很多事情,我只需要插入其中(