C# 如何处理.net web应用程序中带有参数的长查询
假设您有一个长而复杂的查询来获取需要的结果,该结果包含一些参数。任何方法都可以,但为了举例说明:C# 如何处理.net web应用程序中带有参数的长查询,c#,web-applications,.net-4.0,sql-server-2008-r2,C#,Web Applications,.net 4.0,Sql Server 2008 R2,假设您有一个长而复杂的查询来获取需要的结果,该结果包含一些参数。任何方法都可以,但为了举例说明: SELECT q.PROD_ID, q.NAME, q.STANDARD_PROD, q.DESCRIPTION, q.PART_NUMBER, q.COMMENTS, q.DESCRIPTION_URL, PROD_CATEGORY.DESCRIPTION AS CATEGORY_DESCRIPTION, PROD_TYPES.DESCRIPTION AS PROD
SELECT
q.PROD_ID, q.NAME, q.STANDARD_PROD, q.DESCRIPTION, q.PART_NUMBER,
q.COMMENTS, q.DESCRIPTION_URL,
PROD_CATEGORY.DESCRIPTION AS CATEGORY_DESCRIPTION,
PROD_TYPES.DESCRIPTION AS PROD_TYPE
FROM
(SELECT
PROD.PROD_ID,
PROD.PROD_TYPE_ID,
PROD.NAME,
PROD.STANDARD_PROD,
PROD.PROD_CATEGORY_ID,
PROD.DESCRIPTION,
PROD.PART_NUMBER,
PROD.COMMENTS,
PROD.DESCRIPTION_URL
FROM
(SELECT
PROD_ID,
PROD_TYPE_ID
FROM
XREF_PRODSYS
WHERE
(PROD_TYPE_ID = (SELECT
PROD_TYPE_ID
FROM
PROD_TYPES
WHERE
(NAME LIKE @prod_type_name)))) AS p
LEFT OUTER JOIN PROD ON p.PROD_ID = PROD.PROD_ID
WHERE
(PROD.NAME LIKE @prod_name)
AND (PROD.HIDDEN = 0)) AS q
LEFT OUTER JOIN PROD_CATEGORY ON q.PROD_CATEGORY_ID = PROD_CATEGORY.PROD_CATEGORY_ID
LEFT OUTER JOIN PROD_TYPES ON q.PROD_TYPE_ID = PROD_TYPES.PROD_TYPE_ID
此特定查询采用两个参数,可能通过GET/POST传递给.NET web应用程序
有没有一种更干净的方法来存储这么长的查询,而不是将其放在webapp页面的C#源中?我知道下面的“快速肮脏”方法很好用,但确实如此
使代码扩展很多,变得有点难以管理。例如:
//inside Page_Load...
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.Parameters.Add("@prod_type_name", SqlDbType.VarChar).Value = _type_name;
cmd.Parameters.Add("@prod_name", SqlDbType.VarChar).Value = _prod_name;
cmd.CommandText = @"
SELECT q.PROD_ID, q.NAME, q.STANDARD_PROD, q.DESCRIPTION, q.PART_NUMBER, q.COMMENTS, q.DESCRIPTION_URL,
PROD_CATEGORY.DESCRIPTION AS CATEGORY_DESCRIPTION, PROD_TYPES.DESCRIPTION AS PROD_TYPE
FROM (SELECT PROD.PROD_ID, PROD.PROD_TYPE_ID, PROD.NAME, PROD.STANDARD_PROD, PROD.PROD_CATEGORY_ID, PROD.DESCRIPTION,
PROD.PART_NUMBER, PROD.COMMENTS, PROD.DESCRIPTION_URL
FROM (SELECT PROD_ID, PROD_TYPE_ID
FROM XREF_PRODSYS
WHERE (PROD_TYPE_ID =
(SELECT PROD_TYPE_ID
FROM PROD_TYPES
WHERE (NAME LIKE @prod_type_name)))) AS p LEFT OUTER JOIN
PROD ON p.PROD_ID = PROD.PROD_ID
WHERE (PROD.NAME LIKE @prod_name) AND (PROD.HIDDEN = 0)) AS q LEFT OUTER JOIN
PROD_CATEGORY ON q.PROD_CATEGORY_ID = PROD_CATEGORY.PROD_CATEGORY_ID LEFT OUTER JOIN
PROD_TYPES ON q.PROD_TYPE_ID = PROD_TYPES.PROD_TYPE_ID
";
//... do stuff with cmd
为什么不把这一切都放到一个存储过程中并调用存储过程,适当地传递参数呢
将其放入存储过程中。或者是一个充满SQL语句字符串常量的文件。这可能是存储过程有意义的地方。它肯定会清理您的源代码。另一个注意事项:经过一些思考,您可以重新编写这个尖锐的查询,如下所示:
SELECT PROD.PROD_ID, PROD.NAME, PROD.STANDARD_PROD, PROD.DESCRIPTION,
PROD.PART_NUMBER, PROD.COMMENTS, PROD.DESCRIPTION_URL,
PROD_CATEGORY.DESCRIPTION AS CATEGORY_DESCRIPTION,
PROD_TYPES.DESCRIPTION AS PROD_TYPE
FROM XREF_PRODSYS
JOIN PROD_TYPES
ON PROD_TYPES.PROD_TYPE_ID = XREF_PRODSYS.PROD_TYPE_ID
LEFT OUTER JOIN PROD
ON p.PROD_ID = PROD.PROD_ID AND PROD.NAME LIKE @prod_name AND PROD.HIDDEN = 0
LEFT OUTER JOIN PROD_CATEGORY
ON q.PROD_CATEGORY_ID = PROD_CATEGORY.PROD_CATEGORY_ID
WHERE PROD_TYPES.NAME LIKE @prod_type_name
你可能会看到进步。(我相信有更好的方法可以获得相同的信息,但我不必猜测/假设数据库是如何设计的。但我希望此查询应该选择PROD,而不是XREF_PRODSYS作为第一个表。)
您的查询有实体框架的味道,对吗?存储过程是Justin列出的一种方法
通常在构建web应用程序时,我和许多其他人会将数据访问层拆分为另一个项目或类。我通常构建5层:数据库(无论您的SQL需要去哪里;应该在IMO中,或者在DB中,或者至少在另一个类中)数据访问层HTML/Razor后面的业务对象层代码。这使得代码更易于管理,同样重要的是可重用 谢谢,这就是我要找的。不过,我不知道找到这个的正确术语。我重新编写了查询,以便更简单地使用连接,而不是下面的子查询。
SELECT PROD.PROD_ID, PROD.NAME, PROD.STANDARD_PROD, PROD.DESCRIPTION,
PROD.PART_NUMBER, PROD.COMMENTS, PROD.DESCRIPTION_URL,
PROD_CATEGORY.DESCRIPTION AS CATEGORY_DESCRIPTION,
PROD_TYPES.DESCRIPTION AS PROD_TYPE
FROM XREF_PRODSYS
JOIN PROD_TYPES
ON PROD_TYPES.PROD_TYPE_ID = XREF_PRODSYS.PROD_TYPE_ID
LEFT OUTER JOIN PROD
ON p.PROD_ID = PROD.PROD_ID AND PROD.NAME LIKE @prod_name AND PROD.HIDDEN = 0
LEFT OUTER JOIN PROD_CATEGORY
ON q.PROD_CATEGORY_ID = PROD_CATEGORY.PROD_CATEGORY_ID
WHERE PROD_TYPES.NAME LIKE @prod_type_name