【问题标题】:LINQ to EF - Find records where string property of a child collection at least partially matches all records in a list of stringsLINQ to EF - 查找子集合的字符串属性至少部分匹配字符串列表中的所有记录的记录
【发布时间】:2013-02-23 04:19:35
【问题描述】:

我目前正在使用 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();

感谢您的帮助!

【问题讨论】:

    标签: linq entity-framework entity-framework-5


    【解决方案1】:

    就在我的脑海中,我会去做这样的事情

    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 在我们可以做到这一点的方式上非常好,然后在函数结束时,我们最终确定可查询对象,基本上说我们刚刚做的所有事情都可以变成单个查询返回数据库。

    我唯一的其他注意事项是您真的想要索引/全文索引成分名称列,否则这不会很好地扩展。

    【讨论】:

    • 卢克 - 非常感谢你 - 它工作得很好!我会确保索引成分名称列。我目前正在通过 Code First 执行此操作。你知道如何通过代码而不是直接在数据库中将其标记为索引吗?
    • 很高兴为您提供帮助 :),Code first 不支持执行此操作的内置方式,但是大多数人在为数据库播种时使用一些原始 SQL 来完成此操作,请参阅 stackoverflow.com/questions/4995642/… 以了解一些详细信息这该怎么做。 (如果您使用的是 EF 迁移,看起来还有一种方法可以让它更整洁)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-22
    • 2012-07-03
    • 1970-01-01
    • 2010-11-12
    • 2011-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多