LINQ to EF - 查找子集合的字符串属性至少部分匹配字符串列表中的所有记录的记录

Lau*_*hey 5 linq entity-framework entity-framework-5

我目前正在使用LINQ和Entity Framework 5.0编写基于Web的"配方"应用程序.我一直在努力解决这个问题,所以任何帮助都非常感谢!

将有一个搜索功能,用户可以在其中输入他们希望配方结果匹配的成分列表.我需要找到所有配方,其中关联的成分集合(名称属性)包含字符串列表中的每个记录的文本(用户搜索术语).例如,请考虑以下两个配方:

Tomato Sauce: Ingredients 'crushed tomatoes', 'basil', 'olive oil'
Tomato Soup:  Ingredients 'tomato paste', 'milk', 'herbs
Run Code Online (Sandbox Code Playgroud)

如果用户使用搜索术语'番茄'和'油',它将返回番茄酱而不是番茄汤.

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;
Run Code Online (Sandbox Code Playgroud)

我也尝试过:

var list = context.Ingredients.Include(ingredient => ingredient.Recipe)
       .Where(il=>ingredientList.All(x=>il.IngredientName.Contains(x)))
       .GroupBy(recipe=>recipe.Recipe).AsQueryable();
Run Code Online (Sandbox Code Playgroud)

谢谢您的帮助!

Not*_*ple 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();

}
Run Code Online (Sandbox Code Playgroud)

然后你可以用它来调用它:

SearchByIngredients("tomatoes", "oil");
Run Code Online (Sandbox Code Playgroud)

要么

var ingredients = new string[]{"tomatoes", "oil"};
SearchByIngredients(ingredients );
Run Code Online (Sandbox Code Playgroud)

这将做的是将where子句附加到每个搜索术语的可查询配方中.多个where子句在SQL中被视为AND(这也是你想要的).Linq在我们可以做到这一点的方式上相当不错,在函数结束时我们最终确定了queriable本质上说我们刚刚做的所有东西都可以变成单个查询回DB.

我唯一的另一个注意事项是你真的想成为索引/全文索引成分名称列,或者这不会非常好地扩展.