9

在代码隐藏中,您可以将 TVP 添加为存储过程的 SqlDbType.Structured 但这在 ASP.NET SqlDataSource 控件中不存在。

我已经将我的数据表存储在会话变量中(不要担心它们很小!),我需要将它们作为参数传递给 SqlDataSource(它有许多数据绑定对象)

我将数据源指向会话变量,但在转换为表类型时失败。

编辑:假设我将 Session 变量排除在等式之外(因为,真的,它完全是切线的)

必须有一种方法可以将 DBType.Structured 附加到 SQLDataSource。我的 Listview 是适当的数据绑定,但它们所附加的存储过程必须采用 TVP

我不敢相信没有办法为 SQLDataSource 发送 TVP 参数?我的替代方案是什么?

EDIT2:我一直在研究为 SqlDataSource 创建一个自定义参数,但在我看来,它的“eval”方法仍然对结构化数据类型不满意

EDIT3:开始出现我唯一的选择是在代码隐藏中为我的数据绑定控件完成所有工作。我添加了一个赏金,以防其他人有一个优雅的解决方案。

EDIT4:也许有一种方法可以将表作为对象传递给存储过程,然后让 SQL Server 将其转换为 TVP?

4

2 回答 2

6

我知道你已经编辑说会话并不重要,但是我能够使用 SessionParameter 来完成这项工作。我感觉它也可以与 ControlParameter 一起使用。

所以你有一个用户定义的表类型:

CREATE TYPE TVPType AS TABLE(
    Col1 int,
    Col2 int)
GO

以及使用它的存储过程:

CREATE PROC TVPProc(@TVP AS TVPType READONLY) AS
    SELECT * FROM @TVP

然后一个 GridView 绑定到从您的存储过程中选择的 SqlDataSource,传递一个 SessionParameter:

<asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSource1" />
<asp:SqlDataSource ID="SqlDataSource1" SelectCommand="TVPProc" runat="server" SelectCommandType="StoredProcedure" ConnectionString="Server=(local)\sqlexpress;Database=Graph;Integrated Security=True">
    <SelectParameters>
        <asp:SessionParameter SessionField="MyDataTable" Name="TVP" />
    </SelectParameters>
</asp:SqlDataSource>

最后是一些将 DataTable 放入会话的东西,尽管你说你已经有了它:

(五)

<script runat="server">
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim MyDataTable As New System.Data.DataTable

        MyDataTable.Columns.AddRange({
            New System.Data.DataColumn("Col1", GetType(integer)),
            New System.Data.DataColumn("Col2", GetType(integer))})

        MyDataTable.Rows.Add(22, 33)
        MyDataTable.Rows.Add(44, 55)
        MyDataTable.Rows.Add(66, 77)

        Session("MyDataTable") = MyDataTable
    End Sub
</script>

(C#)

<script runat="server">
    protected void Page_Load(object sender, EventArgs e)
    {
        System.Data.DataTable MyDataTable = new System.Data.DataTable();
        MyDataTable.Columns.AddRange(
            new System.Data.DataColumn[] {
                new System.Data.DataColumn("Col1", typeof (int)),
                new System.Data.DataColumn("Col2", typeof (int))});

        MyDataTable.Rows.Add(22, 33);
        MyDataTable.Rows.Add(44, 55);
        MyDataTable.Rows.Add(66, 77);

        Session["MyDataTable"] = MyDataTable;
    }
</script>

这会产生一个精细绑定的 GridView:

替代文字

以及从 Profiler 生成的以下查询:

declare @p1 dbo.TVPType
insert into @p1 values(22,33)
insert into @p1 values(44,55)
insert into @p1 values(66,77)

exec TVPProc @TVP=@p1

这是 .NET 4,MSSQL Express 2010,但也应该工作得更低。

于 2010-08-31T17:10:52.210 回答
0

制作中间类或适配器,作为您已经拥有的任何自动数据边界的源。然后,您可以完全控制为存储过程准备 args,完全按照它需要的方式。

于 2010-08-26T10:44:21.860 回答