我目前正在使用LINQ和Entity Framework 5.0编写基于Web的“配方”应用程序。我一直在努力解决这个问题,所以非常感谢任何帮助!
将有一个搜索功能,用户可以在其中输入他们希望配方结果匹配的成分列表。我需要找到所有配方,其中关联的成分集合(名称属性)包含字符串列表中的每个记录的文本(用户搜索术语)。例如,请考虑以下两个配方:
Tomato Sauce: Ingredients 'crushed tomatoes', 'basil', 'olive oil'
Tomato Soup: Ingredients 'tomato paste', 'milk', 'herbs
如果用户使用搜索词“番茄”和“油”,它会返回番茄酱而不是番茄汤。
var allRecipes = context.Recipes
.Include(recipeCategory => recipeCategory.Category)
.Include(recipeUser => recipeUser.User);
IQueryable<Recipe> r =
from recipe in allRecipes
let ingredientNames =
(from ingredient in recipe.Ingredients
select ingredient.IngredientName)
from i in ingredientNames
let ingredientsToSearch = i where ingredientList.Contains(i)
where ingredientsToSearch.Count() == ingredientList.Count()
select recipe;
我也试过了:
var list = context.Ingredients.Include(ingredient => ingredient.Recipe)
.Where(il=>ingredientList.All(x=>il.IngredientName.Contains(x)))
.GroupBy(recipe=>recipe.Recipe).AsQueryable();
感谢您的帮助!
答案 0 :(得分:6)
在我的头顶上,我会选择这样的东西
public IEnumerable<Recipe> SearchByIngredients(params string[] ingredients)
{
var recipes = context.Recipes
.Include(recipeCategory => recipeCategory.Category)
.Include(recipeUser => recipeUser.User);
foreach(var ingredient in ingredients)
{
recipes = recipes.Where(r=>r.Ingredients.Any(i=>i.IngredientName.Contains(ingredient)));
}
//Finialise the queriable
return recipes.AsEnumerable();
}
然后您可以使用以下方式调用它:
SearchByIngredients("tomatoes", "oil");
或
var ingredients = new string[]{"tomatoes", "oil"};
SearchByIngredients(ingredients );
这样做的目的是为每个搜索字词附加where查询条款。多个where子句在SQL中被视为AND(这也是你想要的)。 Linq在我们可以做到这一点的方式上相当不错,在函数结束时我们最终确定了queriable本质上说我们刚刚做的所有东西都可以变成单个查询回DB。
我唯一的另一个注意事项是你真的想要将成分名称列编入索引/全文索引,或者这样做不会非常好。