我有一个代表食谱所有成分的课程
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的List,它看起来像这样:
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)
})
但是这会返回一个List,我需要将它分解为相同的结构。
以下是使用的类:
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;
}
}
答案 0 :(得分: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();
答案 1 :(得分: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);
}
}
}