Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何将多个查询与EntityFramework相交以进行搜索?_C#_Asp.net Mvc_Linq_Search_Entity Framework 4 - Fatal编程技术网

C# 如何将多个查询与EntityFramework相交以进行搜索?

C# 如何将多个查询与EntityFramework相交以进行搜索?,c#,asp.net-mvc,linq,search,entity-framework-4,C#,Asp.net Mvc,Linq,Search,Entity Framework 4,当人们搜索我的网站时,我不想只搜索值(q),我想用空格作为分隔符搜索每个单词。我编写了大部分代码,但有些部分我不知道怎么做 你能检查一下下面代码中的“待办事项”并给我一个建议吗?或者完全不同的方法。顺便说一下,如果可能的话,我想保留SQL代码部分,因为这对我来说更自然,但所有的TODO都可以在LINQ中完成 谢谢 代码如下: [HttpPost] public ActionResult Search(string q) { ViewBag.

当人们搜索我的网站时,我不想只搜索值(q),我想用空格作为分隔符搜索每个单词。我编写了大部分代码,但有些部分我不知道怎么做

你能检查一下下面代码中的“待办事项”并给我一个建议吗?或者完全不同的方法。顺便说一下,如果可能的话,我想保留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);
        }

以下代码将完成此操作:

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

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

        var recipies = selectedRecipies.Aggregate((a, i) => a.Intersect(i));
var selectedRecipies=new List();
foreach(…)
{
...
选择配方。添加(配方温度);
}
var recipies=所选的详细信息聚合((a,i)=>a.Intersect(i));

此外,在您的位置上,我还将考虑@KirkWoll的注释,并使用FullTextSearch而不是LIKEs。

对于
strquerys
中的每个
str
,您将创建一个按名称排序并存储在
列表中的不同格式的SQL查询,其中
T
是一个
Recipe
(?)。试试这样:

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);

之后,
所有配方
应按类型
IEnumerable
分类

尝试这种方法,它将生成一条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();
}

如果这里有一个“配方”,那就是SQL注入攻击。除了安全问题之外,你对如何做到这一点有什么想法吗?在这种情况下,您建议如何避免SQL注入攻击?我不确定,但我认为使用您的方法,第一个名称将仅在配方名称中搜索,而另一个名称将在所有其他位置(标签、配料等)搜索。我想在这4个地方搜索拆分中的所有名称。但我理解你答案背后的想法,并将在今晚尝试实现它。我知道什么是FullTextSearch(例如Lucene),但我一直认为它是在大量文本中搜索。在我的例子中,我只搜索4个非常小的表(长度为50的varchar)。FullTextSearch与此匹配吗?是的,MSSQL中有一个“内置”FullTextSearch功能,因此您不必安装Lucene。尽管如此,它会在大量文本或Synomins的搜索中显示出来,因此您可能会暂时忘记它,因为它实际上会成为您的一个问题。请注意,我使用您的技术,并将查询中SQL中的部分翻译为linq,以避免SQL注入!非常感谢:)