asp.net 用于搜索的SQL返回错误结果

emeijp43  于 2023-04-13  发布在  .NET
关注(0)|答案(1)|浏览(127)

我在Access数据库中有3个表:ItemRecipeItemInRecipe-包含recipeId和itemId(配方中的项目)。
我在我的Dbf类中有这个方法,这意味着返回一个食谱id列表,其中包含来自itemList的所有项目:

public static List<int> GetTheRecipesIdsWithAllItems(List<string> itemList)
        {
            List<int> recipeIdList = new List<int>();
            string query = "SELECT recipeId FROM ItemInRecipe WHERE itemId IN " +
                "(SELECT itemId FROM Item WHERE itemName IN (" +
                string.Join(",", itemList.ConvertAll(i => "'" + i + "'")) +
                ")) GROUP BY recipeId HAVING COUNT(itemId) = " + itemList.Count;
            DataTable dt = Dbf.GetInfo_fromTable(query); //returns datatable with the information
            foreach (DataRow dr in dt.Rows)
            {
                int recipeId = int.Parse(dr["recipeId"].ToString());
                recipeIdList.Add(recipeId);
            }
            return recipeIdList;
        }

这是在我的服务器WebService1

[WebMethod]
        public List<int> GetTheRecipesIdsWithAllItems(List<string> itemList)
        {
            return Dbf.GetTheRecipesIdsWithAllItems(itemList);
        }

我尝试在我的aspx页面中使用该方法:

public localhost.WebService1 w = new localhost.WebService1();

protected void selectItems_Click(object sender, EventArgs e)
        {
            List<string> l = GetList(); //gets a list of items names
            int[] recipeIdList = w.GetTheRecipesIdsWithAllItems(l.ToArray());
            Recipe[] recipes = w.GetRecipesByIds(recipeIdList.ToArray()); //returns a list of recipes from their ids
            Session["recipeswithitems"] = recipes;
        }

当尝试使用会话中的列表时,它显示为空,我多次更改SQL,但无法找到它不工作的原因。

68bkxrlz

68bkxrlz1#

您的主要问题似乎是缺乏参数化,这导致查询返回不正确的结果。
首先创建一个表类型

CREATE TYPE dbo.ItemList (itemName varchar(100) NOT NULL PRIMARY KEY);

然后将其作为参数传入。表类型有点复杂:你需要创建一个包含数据的DataTable

public static List<int> GetTheRecipesIdsWithAllItems(List<string> itemList)
{
    List<int> recipeIdList = new List<int>();
    const string query = @"
SELECT
  ir.recipeId
FROM ItemInRecipe ir
JOIN Item i ON i.itemId = ir.itemId
JOIN @items it ON it.itemName = i.itemName
GROUP BY
  ir.recipeId
HAVING COUNT(*) = @count;
";

    var dt = new DataTable { Columns = { { "itemName", typeof(string) } } };
    foreach (var item in itemList)
        dt.Rows.Add(item);

    using var conn = new SqlConnection(connString);
    using var comm = new SqlCommand(query, conn);
    {
        comm.Parameters.Add(new SqlParameter("@items", SqlDbType.Structured)
        {
            Value = dt,
            TypeName = "dbo.ItemList",
        });
        comm.Parameters.Add("@count", SqlDbType.Int).Value = itemList.Count;
        conn.Open();
        using var d = comm.ExecuteReader();
        {
            while (reader.Read())
            {
                recipeIdList.Add((int)dr["recipeId"]);
            }
        }
    }
    return recipeIdList;
}

相关问题