0

人々が私のウェブサイトを検索するとき、私は値(q)だけを検索するのではなく、スペースを区切り文字として各単語を検索したいと思います。私はほとんどのコードを作成しましたが、方法がわからない部分があります。

以下のコードの「todo」を確認して、その方法を提案していただけますか?あるいは、まったく異なるアプローチかもしれません。ちなみに、SQLコードの部分は、私にとっては自然なことなので、可能であれば残しておきたいと思いますが、すべてのTODOはLINQで実行できます。

ありがとう

コードは次のとおりです。

[HttpPost]
        public ActionResult Search(string q)
        {
            ViewBag.q = q;

            String[] strQueries = q.Split(' ');

            //TODO: Create an array of type var???

            foreach (string str in strQueries)
            {
                var recipesTemp = db.Recipes.SqlQuery(
                String.Format(
                "SELECT * FROM Recipe WHERE Name LIKE '%{0}%' " +
                "UNION ALL " +
                "SELECT * FROM Recipe WHERE IDRecipe IN ( " +
                "    SELECT IDRecipe FROM Subtitle WHERE Name LIKE '%{0}%') " +
                "UNION ALL  " +
                "SELECT * FROM Recipe WHERE IDRecipe IN ( " +
                "    SELECT IDRecipe FROM RecipeTag " +
                "        INNER JOIN Tag ON Tag.IDTag = RecipeTag.IDTag  " +
                "    WHERE Name LIKE '%{0}%') " +
                "UNION ALL   " +
                "SELECT * FROM Recipe WHERE IDRecipe IN ( " +
                "    SELECT IDRecipe FROM Subtitle " +
                "        INNER JOIN Ingredient ON Ingredient.IDSubtitle = Subtitle.IDSubtitle  " +
                "    WHERE QuantityAndName LIKE '%{0}%')", str)).Distinct().OrderBy(r => r.Name).ToList();

                //TODO: Add recipesTemp to the array of var
            }

            var recipes = //TODO: INTERSECT the results from all the recipesTemp in the array of type var

            return View("Search", recipes);
        }
4

3 に答える 3

1

次のコードはトリックを行います:

        var selectedRecipies = new List<IEnumerable<Recipy>>();

        foreach(...)
        {
            ...
            selectedRecipies.Add(recipesTemp);
        }

        var recipies = selectedRecipies.Aggregate((a, i) => a.Intersect(i));

また、@KirkWoll のコメントも考慮して、LIKE の代わりに FullTextSearch を使用します。

于 2013-02-21T08:15:58.457 に答える
0

単一の SQL ステートメントになるこのアプローチを試してください。

var names = q.Split(' ');

if(names.Any())
{
    var firstName = names[0];

    var query = context.Recipes.Where (q => q.Name.Contains(firstName));
    // other unions ...
    // query = query.Union( context.Recipes.Where (...
    foreach (var name in names.Skip(1))
    {
        query = query.Union(context.Recipes.Where (q => q.Name.Contains(name)));
        // other unions ...
        // query = query.Union( context.Recipes.Where (...
    }

    // query evaluated now
    var recipes = query.ToList();
}
于 2013-02-21T09:32:44.283 に答える
0

のそれぞれについて、名前でソートされ、(?)の場所に格納された、個別にフォーマットされた SQL クエリを作成していますstr。そのようなことを試してください:strQueriesList<T>TRecipe

var allRecipes = strQueries.Select(str => db.Recipes.SqlQuery(
    String.Format(
        "SELECT * FROM Recipe WHERE Name LIKE '%{0}%' " +
        "UNION ALL " +
        "SELECT * FROM Recipe WHERE IDRecipe IN ( " +
        "    SELECT IDRecipe FROM Subtitle WHERE Name LIKE '%{0}%') " +
        "UNION ALL  " +
        "SELECT * FROM Recipe WHERE IDRecipe IN ( " +
        "    SELECT IDRecipe FROM RecipeTag " +
        "        INNER JOIN Tag ON Tag.IDTag = RecipeTag.IDTag  " +
        "    WHERE Name LIKE '%{0}%') " +
        "UNION ALL   " +
        "SELECT * FROM Recipe WHERE IDRecipe IN ( " +
        "    SELECT IDRecipe FROM Subtitle " +
        "        INNER JOIN Ingredient ON Ingredient.IDSubtitle = Subtitle.IDSubtitle  " +
        "    WHERE QuantityAndName LIKE '%{0}%')", str)).Distinct().OrderBy(recipe => recipe.Name))
    .SelectMany(recipe => recipe);

その後allRecipes、タイプの必要がありIEnumerable<Recipe>ます。

于 2013-02-21T08:27:47.220 に答える