关于最小化存储过程参数的建议

时间:2011-01-04 00:48:53

标签: asp.net-mvc sql-server-2008 stored-procedures entity-framework-4 parameter-passing

我有一个ASP.NET MVC Web应用程序,它通过Entity Framework 4.0与SQL Server 2008数据库交互。

在特定页面上,我调用存储过程以根据UI上的选择撤回一些结果。

现在,用户界面有大约20种不同的输入选择,包括文本框,下拉列表,复选框等。

每个输入都被“分组”成逻辑部分。

示例:

  • 搜索框:“Foo”
  • 复选框A1:勾选,复选框A2:未选中
  • 下拉A:选择了选项3
  • 复选框B1:勾选,复选框B2:勾选,复选框B3:未勾选

所以我需要像这样打电话给SPROC:

exec SearchPage_FindResults @SearchQuery = 'Foo', @IncludeA1 = 1, @IncludeA2 = 0, @DropDownSelection = 3, @IncludeB1 = 1, @IncludeB2 = 1, @IncludeB3 = 0

UI对于这个问题并不重要 - 只是想提供一些观点。

基本上,我正在撤回搜索查询的结果,根据用户可以过滤的一堆(可选)选项过滤这些结果。

现在,我的问题/疑问:

  • 将这些参数传递给存储过程的最佳方法是什么?
  • 是否有任何技巧/新方式(例如SQL Server 2008)来执行此操作?特殊的“表”参数/数组 - 我们可以通过用户定义的类型吗?请记住我使用Entity Framework 4.0 - 但如果需要,可以随时使用经典的ADO.NET。
  • XML怎么样?这里的序列化/反序列化成本是多少?值得吗?
  • 每个逻辑部分的参数怎么样?逗号分开也许吧?只是大声思考。

从用户的角度来看,此页面非常重要,并且需要执行得非常好。存储过程的逻辑已经很重,所以我想尽量减少性能影响 - 所以请记住这一点。

话虽如此 - 这里最好的方法是什么?

1 个答案:

答案 0 :(得分:3)

通过快速谷歌搜索,看起来实体框架不支持它们,但您可以在ADO中使用表值参数。

您可以通过在服务器中定义表类型来管理它:

CREATE TYPE yourTypeName AS TABLE (
    columnName <column type>
    -- more columns if you wish, too
)

然后通过创建一个SqlCommand来使用它,并执行以下操作:

SqlParameter param = command.CreateParameter();
param.ParameterName = "@something"
param.SqlDbType = SqlDbType.Structured
param.Value = // a DataTable which matches your table type, I can stick in code I use if you like
param.TypeName = "table type name";

您的程序将如下所示:

CREATE PROCEDURE procName
@something yourTypeName READONLY
AS
BEGIN
...

然后,您的SQL查询将使用该参数,就像它是一个表一样,尽管它是只读的。

性能方面,我不是DBA,我不确定XML的速度有多快 - 我收集它的速度非常快。虽然TVP速度非常快,但即使是我使用过的相对简单的DataTable方法运行也很棒。有关TVP here的更多信息,以及一些关于SQL和TVP的博客文章。