我在尝试将多个嵌套循环转换为lambda或linq表达式时遇到了麻烦。我认为在使用.All或.Contains方法时,我很难理解如何正确访问属性。无论如何,非常感谢帮助。 (我已经阅读了关于这个主题的其他几篇文章,但我仍然在努力使其发挥作用。)
以下是类的内容:
public class RecipeSearch
{
public List<Recipe> Recipe { get; set; }
public List<Meal> MealSettings { get; set; }
public List<Ingredient> MainIngredient { get; set; }
}
public class Meal
{
public int Id { get; set; }
public bool Value { get; set; }
public string DisplayName { get; set; }
}
public class MainIngredient
{
public int Id { get; set; }
public bool Value { get; set; }
public string DisplayName { get; set; }
}
这是嵌套循环:
IEnumerable<Recipe> recipeList = dbContext.Recipes
.OrderBy(r => r.name)
.Where(r => r.name.Contains(name) || string.IsNullOrEmpty(name))
.ToList();
//Model object is of type RecipeSearch
IEnumerable<Meal> selectedMeals = model.MealSettings.Where(x => x.Value == true);
IEnumerable<MainIngredient> selectedIngredients = model.MainIngredient.Where(x => x.Value == true);
foreach (var selected in recipeList) //loop through the master list
{
foreach (var item in selectedMeals) //loop through selected meal categories
{
if (selected.mealCategoryId == item.Id) //passed the meal category check (i.e. it exists)
{
foreach (var ingredient in selectedIngredients) // selected master ingredients
{
if (selected.Ingredients.Any(x => x.SubCategory.mainCategoryid == ingredient.Id))
{
recipe.Recipe.Add(selected);
break;
}
}
}
}
}
我认为应该注意循环完全按预期工作。我只是觉得它的lambda / linq更干净。
编辑:以下是其他对象:
public partial class Recipe
{
public Recipe()
{
Directions = new HashSet<Direction>();
Images = new HashSet<Image>();
Ingredients = new HashSet<Ingredient>();
Nutritions = new HashSet<Nutrition>();
Ratings = new HashSet<Rating>();
}
public int recipeId { get; set; }
//Removed other properties that are not relevant
public virtual ICollection<Ingredient> Ingredients { get; set; }
public virtual MealCategory MealCategory { get; set; }
public virtual RecipeStatus RecipeStatus { get; set; }
}
public partial class Ingredient
{
public int ingredientId { get; set; }
public int? recipeId { get; set; }
public int? subCategoryId { get; set; }
public int measurementId { get; set; }
public int amount { get; set; }
public virtual Recipe Recipe { get; set; }
public virtual SubCategory SubCategory { get; set; }
public virtual Measurement Measurement { get; set; }
}
public partial class SubCategory
{
public SubCategory()
{
Ingredients = new HashSet<Ingredient>();
}
public int subCategoryId { get; set; }
[Required]
[StringLength(255)]
public string name { get; set; }
public int? mainCategoryid { get; set; }
public virtual ICollection<Ingredient> Ingredients { get; set; }
public virtual Maincategory Maincategory { get; set; }
}
答案 0 :(得分:3)
这会有用吗?
var query = from selected in receipeList
join item in selectedMeals on selected.MealCategoryId equals item.Id
where selected.Ingredients.Select(x => x.SubCategory.mainCategoryid.Value)
.Intersect(selectedIngredients.Select(s => s.Id)).Count() > 0
select selected;
foreach(var sel in query)
recipe.Recipe.Add(sel);
我无法看到你从哪里获得recipe.Recipe
。
基本上是为了帮助您将其翻译成linq并根据需要进行调整:
这:
foreach (var selected in recipeList) //loop through the master list
{
foreach (var item in selectedMeals) //loop through selected meal categories
{
if (selected.mealCategoryId == item.Id) //passed the meal category check (i.e. it exists)
{
}
}
}
像这样翻译成连接:
from selected in receipeList
join item in selectedMeals on selected.MealCategoryId equals item.Id
另外,这些行:
if (selected.Ingredients.Any(x => x.SubCategory.mainCategoryid == ingredient.Id))
{
recipe.Recipe.Add(selected);
break;
}
可以翻译成:
where selected.Ingredients.Select(x => x.SubCategory.mainCategoryid.Value)
.Intersect(selectedIngredients.Select(s => s.Id)).Count() > 0
select selected;
//and then
foreach(var sel in query)
recipe.Recipe.Add(sel);
答案 1 :(得分:0)
请注意以下部分,
IEnumerable<Recipe> recipeList = dbContext.Recipes
.OrderBy(r => r.name)
.Where(r => r.name.Contains(name) || string.IsNullOrEmpty(name))
.ToList();
这里有两件事: 首先,你应该先交换or-condition来检查String.IsNullOrEmpty,然后 第二个把orderby之前的位置减少,以减少需要订购的物品。
IEnumerable<Recipe> recipeList = dbContext.Recipes
.Where(r => string.IsNullOrEmpty(name) || r.name.Contains(name))
.OrderBy(r => r.name)
.ToList();
根据ItemCount,这可能会给你一些&#34;提升&#34;。